Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset f039dba in mainline


Ignore:
Timestamp:
2012-08-17T09:57:27Z (9 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
b1912b0c
Parents:
f72ae3b
Message:

Logger also works with hierarchy

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/logset/main.c

    rf72ae3b rf039dba  
    7171        } else if (argc == 3) {
    7272                log_level_t new_level = parse_log_level_or_die(argv[2]);
    73                 const char *toplog = argv[1];
    74                 int rc = logctl_set_top_log_level(toplog, new_level);
     73                const char *logname = argv[1];
     74                int rc = logctl_set_log_level(logname, new_level);
    7575
    76                 if (rc != EOK) {
    77                         fprintf(stderr, "Failed to change logging level: %s.\n",
    78                             str_error(rc));
    79                         return 2;
    80                 }
    81         } else if (argc == 4) {
    82                 log_level_t new_level = parse_log_level_or_die(argv[3]);
    83                 const char *toplog = argv[1];
    84                 const char *log = argv[2];
    85                 int rc = logctl_set_log_level(toplog, log, new_level);
    8676                if (rc != EOK) {
    8777                        fprintf(stderr, "Failed to change logging level: %s.\n",
  • uspace/lib/c/generic/io/log.c

    rf72ae3b rf039dba  
    4343#include <ns.h>
    4444
    45 typedef struct {
    46         char *name;
    47         sysarg_t top_log_id;
    48         sysarg_t log_id;
    49 } log_info_t;
    50 
    51 static log_info_t default_log = {
    52         .name = NULL,
    53         .top_log_id = 0,
    54         .log_id = 0
    55 };
    56 
    57 static sysarg_t default_top_log_id;
     45static sysarg_t default_log_id;
    5846
    5947/** Log messages are printed under this name. */
     
    8573
    8674        ipc_call_t answer;
    87         aid_t reg_msg = async_send_0(exchange, LOGGER_WRITER_CREATE_TOPLEVEL_LOG, &answer);
     75        aid_t reg_msg = async_send_1(exchange, LOGGER_WRITER_CREATE_LOG, LOG_NO_PARENT, &answer);
    8876        int rc = async_data_write_start(exchange, prog_name, str_size(prog_name));
    8977        sysarg_t reg_msg_rc;
     
    9987                return reg_msg_rc;
    10088
    101         default_top_log_id = IPC_GET_ARG1(answer);
    102         default_log.top_log_id = default_top_log_id;
     89        default_log_id = IPC_GET_ARG1(answer);
    10390
    10491        return EOK;
    10592}
    10693
    107 static int logger_message(async_sess_t *session, log_t ctx, log_level_t level, const char *message)
     94static int logger_message(async_sess_t *session, log_t log, log_level_t level, const char *message)
    10895{
    10996        async_exch_t *exchange = async_exchange_begin(session);
     
    11198                return ENOMEM;
    11299        }
    113         log_info_t *log_info = ctx != 0 ? (log_info_t *) ctx : &default_log;
    114 
    115         aid_t reg_msg = async_send_3(exchange, LOGGER_WRITER_MESSAGE,
    116             log_info->top_log_id, log_info->log_id, level, NULL);
     100        if (log == LOG_DEFAULT)
     101                log = default_log_id;
     102
     103        aid_t reg_msg = async_send_2(exchange, LOGGER_WRITER_MESSAGE,
     104            log, level, NULL);
    117105        int rc = async_data_write_start(exchange, message, str_size(message));
    118106        sysarg_t reg_msg_rc;
     
    206194log_t log_create(const char *name, log_t parent)
    207195{
    208         log_info_t *info = malloc(sizeof(log_info_t));
    209         if (info == NULL)
    210                 return LOG_DEFAULT;
    211         info->name = NULL;
    212 
    213         if (parent == LOG_DEFAULT) {
    214                 info->name = str_dup(name);
    215                 if (info->name == NULL)
    216                         goto error;
    217                 info->top_log_id = default_top_log_id;
    218         } else {
    219                 log_info_t *parent_info = (log_info_t *) parent;
    220                 int rc = asprintf(&info->name, "%s/%s",
    221                     parent_info->name, name);
    222                 if (rc < 0)
    223                         goto error;
    224                 info->top_log_id = parent_info->top_log_id;
    225         }
    226 
    227196        async_exch_t *exchange = async_exchange_begin(logger_session);
    228197        if (exchange == NULL)
    229                 goto error;
     198                return parent;
     199
     200        if (parent == LOG_DEFAULT)
     201                parent = default_log_id;
    230202
    231203        ipc_call_t answer;
    232         aid_t reg_msg = async_send_1(exchange, LOGGER_WRITER_CREATE_SUB_LOG,
    233             info->top_log_id, &answer);
    234         int rc = async_data_write_start(exchange, info->name, str_size(info->name));
     204        aid_t reg_msg = async_send_1(exchange, LOGGER_WRITER_CREATE_LOG,
     205            parent, &answer);
     206        int rc = async_data_write_start(exchange, name, str_size(name));
    235207        sysarg_t reg_msg_rc;
    236208        async_wait_for(reg_msg, &reg_msg_rc);
     
    239211
    240212        if ((rc != EOK) || (reg_msg_rc != EOK))
    241                 goto error;
    242 
    243         info->log_id = IPC_GET_ARG1(answer);
    244         return (sysarg_t) info;
    245 
    246 error:
    247         free(info->name);
    248         free(info);
    249         return parent;
     213                return parent;
     214
     215        return IPC_GET_ARG1(answer);
    250216}
    251217
  • uspace/lib/c/generic/io/logctl.c

    rf72ae3b rf039dba  
    8181}
    8282
    83 int logctl_set_top_log_level(const char *namespace, log_level_t new_level)
    84 {
    85         async_exch_t *exchange = NULL;
    86         int rc = start_logger_exchange(&exchange);
    87         if (rc != EOK)
    88                 return rc;
    89 
    90         aid_t reg_msg = async_send_1(exchange, LOGGER_CTL_SET_TOP_LOG_LEVEL,
    91             new_level, NULL);
    92         rc = async_data_write_start(exchange, namespace, str_size(namespace));
    93         sysarg_t reg_msg_rc;
    94         async_wait_for(reg_msg, &reg_msg_rc);
    95 
    96         async_exchange_end(exchange);
    97 
    98         if (rc != EOK) {
    99                 return rc;
    100         }
    101 
    102         return (int) reg_msg_rc;
    103 }
    104 
    105 int logctl_set_log_level(const char *namespace, const char *context, log_level_t new_level)
     83int logctl_set_log_level(const char *logname, log_level_t new_level)
    10684{
    10785        async_exch_t *exchange = NULL;
     
    11290        aid_t reg_msg = async_send_1(exchange, LOGGER_CTL_SET_LOG_LEVEL,
    11391            new_level, NULL);
    114         rc = async_data_write_start(exchange, namespace, str_size(namespace));
    115         int rc2 = async_data_write_start(exchange, context, str_size(context));
     92        rc = async_data_write_start(exchange, logname, str_size(logname));
    11693        sysarg_t reg_msg_rc;
    11794        async_wait_for(reg_msg, &reg_msg_rc);
     
    12299                return rc;
    123100
    124         if (rc2 != EOK)
    125                 return rc2;
    126 
    127101        return (int) reg_msg_rc;
    128102}
  • uspace/lib/c/include/io/log.h

    rf72ae3b rf039dba  
    5353typedef sysarg_t log_t;
    5454#define PRIlogctx PRIxn
    55 #define LOG_DEFAULT 0
     55#define LOG_DEFAULT ((log_t) -1)
     56#define LOG_NO_PARENT ((log_t) 0)
    5657
    5758extern const char *log_level_str(log_level_t);
  • uspace/lib/c/include/io/logctl.h

    rf72ae3b rf039dba  
    3737
    3838extern int logctl_set_default_level(log_level_t);
    39 extern int logctl_set_top_log_level(const char *, log_level_t);
    40 extern int logctl_set_log_level(const char *, const char *, log_level_t);
     39extern int logctl_set_log_level(const char *, log_level_t);
    4140
    4241#endif
  • uspace/lib/c/include/ipc/logger.h

    rf72ae3b rf039dba  
    3838typedef enum {
    3939        LOGGER_CTL_SET_DEFAULT_LEVEL = IPC_FIRST_USER_METHOD,
    40         LOGGER_CTL_SET_TOP_LOG_LEVEL,
    4140        LOGGER_CTL_SET_LOG_LEVEL
    4241} logger_control_request_t;
     
    4443typedef enum {
    4544        /** Followed by STRING, returns ID to be used for CREATE_SUB_LOG */
    46         LOGGER_WRITER_CREATE_TOPLEVEL_LOG = IPC_FIRST_USER_METHOD,
    47         LOGGER_WRITER_CREATE_SUB_LOG,
     45        LOGGER_WRITER_CREATE_LOG = IPC_FIRST_USER_METHOD,
    4846        LOGGER_WRITER_MESSAGE
    4947} logger_writer_request_t;
  • uspace/srv/logger/ctl.c

    rf72ae3b rf039dba  
    4343#include "logger.h"
    4444
    45 static int handle_toplog_level_change(sysarg_t new_level)
     45static int handle_log_level_change(sysarg_t new_level)
    4646{
    47         void *top_name;
    48         int rc = async_data_write_accept(&top_name, true, 0, 0, 0, NULL);
     47        void *full_name;
     48        int rc = async_data_write_accept(&full_name, true, 0, 0, 0, NULL);
    4949        if (rc != EOK) {
    5050                return rc;
    5151        }
    5252
    53         logger_toplevel_log_t *toplog = find_or_create_toplevel_log(top_name);
    54         free(top_name);
    55         if (toplog == NULL)
     53        logger_log_t *log = find_log_by_name(full_name);
     54        free(full_name);
     55        if (log == NULL)
    5656                return ENOENT;
    5757
    58         toplog->logged_level = new_level;
     58        log->logged_level = new_level;
    5959
    6060        return EOK;
    61 }
    62 
    63 static int handle_log_level_change(sysarg_t new_level)
    64 {
    65         void *top_name;
    66         int rc = async_data_write_accept(&top_name, true, 0, 0, 0, NULL);
    67         if (rc != EOK) {
    68                 return rc;
    69         }
    70 
    71         logger_toplevel_log_t *toplog = find_or_create_toplevel_log(top_name);
    72         free(top_name);
    73         if (toplog == NULL)
    74                 return ENOENT;
    75 
    76 
    77         void *log_name;
    78         rc = async_data_write_accept(&log_name, true, 0, 0, 0, NULL);
    79         if (rc != EOK)
    80                 return rc;
    81 
    82         rc = ENOENT;
    83         for (size_t i = 0; i < toplog->sublog_count; i++) {
    84                 if (str_cmp(toplog->sublogs[i].name, (const char *) log_name) == 0) {
    85                         toplog->sublogs[i].logged_level = new_level;
    86                         rc = EOK;
    87                         break;
    88                 }
    89         }
    90 
    91         free(log_name);
    92 
    93         return rc;
    9461}
    9562
     
    10976                case LOGGER_CTL_SET_DEFAULT_LEVEL: {
    11077                        int rc = set_default_logging_level(IPC_GET_ARG1(call));
    111                         async_answer_0(callid, rc);
    112                         break;
    113                 }
    114                 case LOGGER_CTL_SET_TOP_LOG_LEVEL: {
    115                         int rc = handle_toplog_level_change(IPC_GET_ARG1(call));
    11678                        async_answer_0(callid, rc);
    11779                        break;
  • uspace/srv/logger/initlvl.c

    rf72ae3b rf039dba  
    6161                return;
    6262
    63         logger_toplevel_log_t *log = find_or_create_toplevel_log(key);
     63        logger_log_t *log = find_or_create_log(key, 0);
    6464        if (log == NULL)
    6565                return;
  • uspace/srv/logger/logger.h

    rf72ae3b rf039dba  
    4848#define LOG_LEVEL_USE_DEFAULT (LVL_LIMIT + 1)
    4949
    50 typedef struct {
    51         const char *name;
    52         log_level_t logged_level;
    53 } logger_sublog_t;
     50typedef struct logger_log logger_log_t;
    5451
    5552typedef struct {
    56         const char *name;
    5753        FILE *logfile;
     54} logger_dest_t;
     55
     56struct logger_log {
     57        link_t link;
     58
     59        char *name;
     60        char *full_name;
     61        logger_log_t *parent;
    5862        log_level_t logged_level;
    59         size_t sublog_count;
    60         logger_sublog_t sublogs[MAX_SUBLOGS];
     63        logger_dest_t *dest;
     64};
    6165
    62         link_t link;
    63 } logger_toplevel_log_t;
    64 
    65 
    66 logger_toplevel_log_t *find_or_create_toplevel_log(const char *);
    67 logger_toplevel_log_t *find_toplevel_log(sysarg_t);
    68 bool shall_log_message(logger_toplevel_log_t *, sysarg_t, log_level_t);
    69 int add_sub_log(logger_toplevel_log_t *, const char *, sysarg_t *);
     66logger_log_t *find_log_by_name(const char *name);
     67logger_log_t *find_or_create_log(const char *name, sysarg_t parent);
     68logger_log_t *find_log_by_id(sysarg_t);
     69bool shall_log_message(logger_log_t *, log_level_t);
    7070
    7171log_level_t get_default_logging_level(void);
  • uspace/srv/logger/logs.c

    rf72ae3b rf039dba  
    3737#include "logger.h"
    3838
    39 static FIBRIL_MUTEX_INITIALIZE(toplog_list_guard);
    40 static LIST_INITIALIZE(toplog_list);
    4139
    42 static logger_toplevel_log_t *find_log_by_name_no_lock(const char *name)
     40static FIBRIL_MUTEX_INITIALIZE(log_list_guard);
     41static LIST_INITIALIZE(log_list);
     42
     43
     44static logger_log_t *find_log_by_name_and_parent_no_lock(const char *name, logger_log_t *parent)
    4345{
    44         list_foreach(toplog_list, it) {
    45                 logger_toplevel_log_t *log = list_get_instance(it, logger_toplevel_log_t, link);
    46                 if (str_cmp(log->name, name) == 0) {
    47                         return log;
    48                 }
    49         }
    50 
    51         return NULL;
    52 }
    53 
    54 logger_toplevel_log_t *find_or_create_toplevel_log(const char *name)
    55 {
    56         logger_toplevel_log_t *result = NULL;
    57 
    58         fibril_mutex_lock(&toplog_list_guard);
    59 
    60         result = find_log_by_name_no_lock(name);
    61         if (result != NULL)
    62                 goto leave;
    63 
    64         result = malloc(sizeof(logger_toplevel_log_t));
    65         if (result == NULL)
    66                 goto leave;
    67 
    68         char *logfilename;
    69         asprintf(&logfilename, "/log/%s", name);
    70         result->logfile = fopen(logfilename, "a");
    71         result->logged_level = LOG_LEVEL_USE_DEFAULT;
    72         result->name = str_dup(name);
    73         result->sublog_count = 1;
    74         result->sublogs[0].name = "";
    75         result->sublogs[0].logged_level = LOG_LEVEL_USE_DEFAULT;
    76 
    77         link_initialize(&result->link);
    78 
    79         list_append(&result->link, &toplog_list);
    80 
    81 leave:
    82         fibril_mutex_unlock(&toplog_list_guard);
    83 
    84         return result;
    85 }
    86 
    87 logger_toplevel_log_t *find_toplevel_log(sysarg_t id)
    88 {
    89         list_foreach(toplog_list, it) {
    90                 logger_toplevel_log_t *log = list_get_instance(it, logger_toplevel_log_t, link);
    91                 if ((sysarg_t) log == id)
     46        list_foreach(log_list, it) {
     47                logger_log_t *log = list_get_instance(it, logger_log_t, link);
     48                if ((parent == log->parent) && (str_cmp(log->name, name) == 0))
    9249                        return log;
    9350        }
     
    9653}
    9754
    98 bool shall_log_message(logger_toplevel_log_t *toplog, sysarg_t log, log_level_t level)
     55static logger_dest_t *create_dest(const char *name)
    9956{
    100         if (log >= toplog->sublog_count)
    101                 return false;
     57        logger_dest_t *result = malloc(sizeof(logger_dest_t));
     58        char *logfilename;
     59        asprintf(&logfilename, "/log/%s", name);
     60        result->logfile = fopen(logfilename, "a");
     61        return result;
     62}
    10263
    103         log_level_t logged_level = toplog->sublogs[log].logged_level;
    104         if (logged_level == LOG_LEVEL_USE_DEFAULT) {
    105                 logged_level = toplog->logged_level;
    106                 if (logged_level == LOG_LEVEL_USE_DEFAULT)
    107                         logged_level = get_default_logging_level();
    108         }
     64logger_log_t *find_or_create_log(const char *name, sysarg_t parent_id)
     65{
     66        logger_log_t *result = NULL;
     67        logger_log_t *parent = (logger_log_t *) parent_id;
     68
     69        fibril_mutex_lock(&log_list_guard);
     70
     71        result = find_log_by_name_and_parent_no_lock(name, parent);
     72        if (result != NULL)
     73                goto leave;
     74
     75        result = malloc(sizeof(logger_log_t));
     76        if (result == NULL)
     77                goto leave;
    10978
    11079
    111         return level <= logged_level;
     80        result->logged_level = LOG_LEVEL_USE_DEFAULT;
     81        result->name = str_dup(name);
     82        if (parent == NULL) {
     83                result->full_name = str_dup(name);
     84                result->dest = create_dest(name);
     85        } else {
     86                asprintf(&result->full_name, "%s/%s", parent->full_name, name);
     87                result->dest = parent->dest;
     88        }
     89        result->parent = parent;
     90
     91        link_initialize(&result->link);
     92
     93        list_append(&result->link, &log_list);
     94
     95leave:
     96        fibril_mutex_unlock(&log_list_guard);
     97
     98        return result;
    11299}
    113100
    114 int add_sub_log(logger_toplevel_log_t *toplog, const char *name, sysarg_t *id)
     101logger_log_t *find_log_by_name(const char *name)
    115102{
    116         if (toplog->sublog_count >= MAX_SUBLOGS)
    117                 return ELIMIT;
     103        logger_log_t *result = NULL;
    118104
    119         logger_sublog_t *sublog =  &toplog->sublogs[toplog->sublog_count];
    120         sublog->name = str_dup(name);
    121         sublog->logged_level = toplog->logged_level;
     105        fibril_mutex_lock(&log_list_guard);
     106        list_foreach(log_list, it) {
     107                logger_log_t *log = list_get_instance(it, logger_log_t, link);
     108                if (str_cmp(log->full_name, name) == 0) {
     109                        result = log;
     110                        break;
     111                }
     112        }
     113        fibril_mutex_unlock(&log_list_guard);
    122114
    123         *id = toplog->sublog_count;
    124 
    125         toplog->sublog_count++;
    126 
    127         return EOK;
     115        return result;
    128116}
    129117
     118logger_log_t *find_log_by_id(sysarg_t id)
     119{
     120        logger_log_t *result = NULL;
     121
     122        fibril_mutex_lock(&log_list_guard);
     123        list_foreach(log_list, it) {
     124                logger_log_t *log = list_get_instance(it, logger_log_t, link);
     125                if ((sysarg_t) log == id) {
     126                        result = log;
     127                        break;
     128                }
     129        }
     130        fibril_mutex_unlock(&log_list_guard);
     131
     132        return result;
     133}
     134
     135static log_level_t get_actual_log_level(logger_log_t *log)
     136{
     137        /* Find recursively proper log level. */
     138        if (log->logged_level == LOG_LEVEL_USE_DEFAULT) {
     139                if (log->parent == NULL)
     140                        return get_default_logging_level();
     141                else
     142                        return get_actual_log_level(log->parent);
     143        }
     144        return log->logged_level;
     145}
     146
     147bool shall_log_message(logger_log_t *log, log_level_t level)
     148{
     149        return level <= get_actual_log_level(log);
     150}
    130151
    131152/**
  • uspace/srv/logger/writer.c

    rf72ae3b rf039dba  
    4949
    5050
    51 static logger_toplevel_log_t *handle_create_toplevel_log(void)
     51static logger_log_t *handle_create_log(sysarg_t parent)
    5252{
    5353        void *name;
     
    5656                return NULL;
    5757
    58         logger_toplevel_log_t *log = find_or_create_toplevel_log(name);
     58        logger_log_t *log = find_or_create_log(name, parent);
    5959
    6060        free(name);
     
    6363}
    6464
    65 static int handle_receive_message(sysarg_t toplevel_log_id, sysarg_t log_id, sysarg_t level)
     65static int handle_receive_message(sysarg_t log_id, sysarg_t level)
    6666{
    67         logger_toplevel_log_t *log = find_toplevel_log(toplevel_log_id);
     67        logger_log_t *log = find_log_by_id(log_id);
    6868        if (log == NULL)
    69                 return ENOENT;
    70 
    71         if (log_id > log->sublog_count)
    7269                return ENOENT;
    7370
     
    7774                return rc;
    7875
    79         if (!shall_log_message(log, log_id, level)) {
     76        if (!shall_log_message(log, level)) {
    8077                free(message);
    8178                return EOK;
    8279        }
    8380
    84         printf("[%s/%s] %s: %s\n",
    85             log->name, log->sublogs[log_id].name,
    86             log_level_str(level),
     81        printf("[%s] %s: %s\n",
     82            log->full_name, log_level_str(level),
    8783            (const char *) message);
    8884
     
    9086
    9187        return EOK;
    92 }
    93 
    94 static int handle_create_sub_log(sysarg_t toplevel_log_id, sysarg_t *log_id)
    95 {
    96         logger_toplevel_log_t *log = find_toplevel_log(toplevel_log_id);
    97         if (log == NULL)
    98                 return ENOENT;
    99 
    100         void *name;
    101         int rc = async_data_write_accept(&name, true, 0, 0, 0, NULL);
    102         if (rc != EOK)
    103                 return rc;
    104 
    105         rc = add_sub_log(log, name, log_id);
    106 
    107         free(name);
    108 
    109         return rc;
    11088}
    11189
     
    125103
    126104                switch (IPC_GET_IMETHOD(call)) {
    127                 case LOGGER_WRITER_CREATE_TOPLEVEL_LOG: {
    128                         logger_toplevel_log_t *log = handle_create_toplevel_log();
     105                case LOGGER_WRITER_CREATE_LOG: {
     106                        logger_log_t *log = handle_create_log(IPC_GET_ARG1(call));
    129107                        if (log == NULL) {
    130108                                async_answer_0(callid, ENOMEM);
     
    136114                case LOGGER_WRITER_MESSAGE: {
    137115                        int rc = handle_receive_message(IPC_GET_ARG1(call),
    138                             IPC_GET_ARG2(call), IPC_GET_ARG3(call));
     116                            IPC_GET_ARG2(call));
    139117                        async_answer_0(callid, rc);
    140                         break;
    141                 }
    142                 case LOGGER_WRITER_CREATE_SUB_LOG: {
    143                         sysarg_t log_id;
    144                         int rc = handle_create_sub_log(IPC_GET_ARG1(call), &log_id);
    145                         async_answer_1(callid, rc, log_id);
    146118                        break;
    147119                }
Note: See TracChangeset for help on using the changeset viewer.