Changes in / [c8444d8:5882487] in mainline


Ignore:
Files:
12 added
10 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile.common

    rc8444d8 r5882487  
    7474        $(USPACE_PATH)/srv/locsrv/locsrv \
    7575        $(USPACE_PATH)/srv/bd/rd/rd \
    76         $(USPACE_PATH)/srv/vfs/vfs
     76        $(USPACE_PATH)/srv/vfs/vfs \
     77        $(USPACE_PATH)/srv/logger/logger
    7778
    7879ifeq ($(RDFMT),tmpfs)
     
    165166        $(USPACE_PATH)/app/killall/killall \
    166167        $(USPACE_PATH)/app/loc/loc \
     168        $(USPACE_PATH)/app/logset/logset \
    167169        $(USPACE_PATH)/app/mkfat/mkfat \
    168170        $(USPACE_PATH)/app/mkexfat/mkexfat \
  • uspace/Makefile

    rc8444d8 r5882487  
    4747        app/klog \
    4848        app/loc \
     49        app/logset \
    4950        app/mkfat \
    5051        app/mkexfat \
     
    7475        srv/clipboard \
    7576        srv/locsrv \
     77        srv/logger \
    7678        srv/devman \
    7779        srv/loader \
  • uspace/app/tester/Makefile

    rc8444d8 r5882487  
    4545        stdio/stdio1.c \
    4646        stdio/stdio2.c \
     47        stdio/logger1.c \
    4748        fault/fault1.c \
    4849        fault/fault2.c \
  • uspace/app/tester/tester.c

    rc8444d8 r5882487  
    3939#include <stdio.h>
    4040#include <str.h>
     41#include <io/log.h>
    4142#include "tester.h"
    4243
     
    5556#include "stdio/stdio1.def"
    5657#include "stdio/stdio2.def"
     58#include "stdio/logger1.def"
    5759#include "fault/fault1.def"
    5860#include "fault/fault2.def"
     
    138140        }
    139141       
     142        log_init("tester", LVL_NOTE);
     143
    140144        test_quiet = false;
    141145        test_argc = argc - 2;
  • uspace/app/tester/tester.h

    rc8444d8 r5882487  
    8888extern const char *test_stdio1(void);
    8989extern const char *test_stdio2(void);
     90extern const char *test_logger1(void);
    9091extern const char *test_fault1(void);
    9192extern const char *test_fault2(void);
  • uspace/lib/c/Makefile

    rc8444d8 r5882487  
    9797        generic/io/printf.c \
    9898        generic/io/log.c \
     99        generic/io/logctl.c \
    99100        generic/io/klog.c \
    100101        generic/io/snprintf.c \
  • uspace/lib/c/generic/io/log.c

    rc8444d8 r5882487  
    3838#include <stdlib.h>
    3939#include <stdio.h>
    40 
     40#include <async.h>
    4141#include <io/log.h>
    42 
    43 /** Serialization mutex for logging functions. */
    44 static FIBRIL_MUTEX_INITIALIZE(log_serializer);
    45 
    46 /** Current log level. */
    47 static log_level_t log_level;
    48 
    49 static FILE *log_stream;
    50 
     42#include <ipc/logger.h>
     43#include <ns.h>
     44
     45/** Log messages are printed under this name. */
    5146static const char *log_prog_name;
    5247
    53 /** Prefixes for individual logging levels. */
    54 static const char *log_level_names[] = {
    55         [LVL_FATAL] = "Fatal error",
    56         [LVL_ERROR] = "Error",
    57         [LVL_WARN] = "Warning",
    58         [LVL_NOTE] = "Note",
    59         [LVL_DEBUG] = "Debug",
    60         [LVL_DEBUG2] = "Debug2"
    61 };
     48/** IPC session with the logger service. */
     49static async_sess_t *logger_session;
     50
     51/** Maximum length of a single log message (in bytes). */
     52#define MESSAGE_BUFFER_SIZE 4096
     53
     54FIBRIL_RWLOCK_INITIALIZE(current_observed_level_lock);
     55log_level_t current_observed_level;
     56
     57static int logger_register(async_sess_t *session, const char *prog_name)
     58{
     59        async_exch_t *exchange = async_exchange_begin(session);
     60        if (exchange == NULL) {
     61                return ENOMEM;
     62        }
     63
     64        aid_t reg_msg = async_send_0(exchange, LOGGER_REGISTER, NULL);
     65        int rc = async_data_write_start(exchange, prog_name, str_size(prog_name));
     66        sysarg_t reg_msg_rc;
     67        async_wait_for(reg_msg, &reg_msg_rc);
     68
     69        async_exchange_end(exchange);
     70
     71        if (rc != EOK) {
     72                return rc;
     73        }
     74
     75        return reg_msg_rc;
     76}
     77
     78static int logger_message(async_sess_t *session, log_level_t level, const char *message)
     79{
     80        async_exch_t *exchange = async_exchange_begin(session);
     81        if (exchange == NULL) {
     82                return ENOMEM;
     83        }
     84
     85        aid_t reg_msg = async_send_1(exchange, LOGGER_MESSAGE, level, NULL);
     86        int rc = async_data_write_start(exchange, message, str_size(message));
     87        sysarg_t reg_msg_rc;
     88        async_wait_for(reg_msg, &reg_msg_rc);
     89
     90        async_exchange_end(exchange);
     91
     92        /*
     93         * Getting ENAK means no-one wants our message. That is not an
     94         * error at all.
     95         */
     96        if (rc == ENAK)
     97                rc = EOK;
     98
     99        if (rc != EOK) {
     100                return rc;
     101        }
     102
     103        return reg_msg_rc;
     104}
     105
     106static void cannot_use_level_changed_monitor(void)
     107{
     108        fibril_rwlock_write_lock(&current_observed_level_lock);
     109        current_observed_level = LVL_LIMIT;
     110        fibril_rwlock_write_unlock(&current_observed_level_lock);
     111}
     112
     113static int observed_level_changed_monitor(void *arg)
     114{
     115        async_sess_t *monitor_session = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOGGER, LOGGER_INTERFACE_SINK, 0);
     116        if (monitor_session == NULL) {
     117                cannot_use_level_changed_monitor();
     118                return ENOMEM;
     119        }
     120
     121        int rc = logger_register(monitor_session, log_prog_name);
     122        if (rc != EOK) {
     123                cannot_use_level_changed_monitor();
     124                return rc;
     125        }
     126
     127        async_exch_t *exchange = async_exchange_begin(monitor_session);
     128        if (exchange == NULL) {
     129                cannot_use_level_changed_monitor();
     130                return ENOMEM;
     131        }
     132
     133        while (true) {
     134                sysarg_t has_reader;
     135                sysarg_t msg_rc = async_req_0_1(exchange,
     136                    LOGGER_BLOCK_UNTIL_READER_CHANGED, &has_reader);
     137                if (msg_rc != EOK) {
     138                        cannot_use_level_changed_monitor();
     139                        break;
     140                }
     141
     142                fibril_rwlock_write_lock(&current_observed_level_lock);
     143                if ((bool) has_reader) {
     144                        current_observed_level = LVL_LIMIT;
     145                } else {
     146                        current_observed_level = LVL_NOTE;
     147                }
     148                fibril_rwlock_write_unlock(&current_observed_level_lock);
     149        }
     150
     151        async_exchange_end(exchange);
     152
     153        return EOK;
     154}
     155
     156static log_level_t get_current_observed_level(void)
     157{
     158        fibril_rwlock_read_lock(&current_observed_level_lock);
     159        log_level_t level = current_observed_level;
     160        fibril_rwlock_read_unlock(&current_observed_level_lock);
     161        return level;
     162}
    62163
    63164/** Initialize the logging system.
     
    69170{
    70171        assert(level < LVL_LIMIT);
    71         log_level = level;
    72 
    73         log_stream = stdout;
     172
    74173        log_prog_name = str_dup(prog_name);
    75174        if (log_prog_name == NULL)
    76175                return ENOMEM;
    77176
    78         return EOK;
     177        logger_session = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOGGER, LOGGER_INTERFACE_SINK, 0);
     178        if (logger_session == NULL) {
     179                return ENOMEM;
     180        }
     181
     182        int rc = logger_register(logger_session, log_prog_name);
     183
     184        current_observed_level = LVL_NOTE;
     185
     186        fid_t observed_level_changed_fibril = fibril_create(observed_level_changed_monitor, NULL);
     187        if (observed_level_changed_fibril == 0) {
     188                cannot_use_level_changed_monitor();
     189        } else {
     190                fibril_add_ready(observed_level_changed_fibril);
     191        }
     192
     193        return rc;
     194}
     195
     196bool __log_shall_record(log_level_t level)
     197{
     198        return get_current_observed_level() >= level;
    79199}
    80200
     
    86206 * @param fmt           Format string (no traling newline).
    87207 */
    88 void log_msg(log_level_t level, const char *fmt, ...)
     208void __log_msg(log_level_t level, const char *fmt, ...)
    89209{
    90210        va_list args;
    91211
    92212        va_start(args, fmt);
    93         log_msgv(level, fmt, args);
     213        __log_msgv(level, fmt, args);
    94214        va_end(args);
    95215}
     
    102222 * @param fmt           Format string (no trailing newline)
    103223 */
    104 void log_msgv(log_level_t level, const char *fmt, va_list args)
     224void __log_msgv(log_level_t level, const char *fmt, va_list args)
    105225{
    106226        assert(level < LVL_LIMIT);
    107227
    108         /* Higher number means higher verbosity. */
    109         if (level <= log_level) {
    110                 fibril_mutex_lock(&log_serializer);
    111 
    112                 fprintf(log_stream, "%s: %s: ", log_prog_name,
    113                     log_level_names[level]);
    114                 vfprintf(log_stream, fmt, args);
    115                 fputc('\n', log_stream);
    116                 fflush(log_stream);
    117 
    118                 fibril_mutex_unlock(&log_serializer);
    119         }
     228        if (get_current_observed_level() < level) {
     229                return;
     230        }
     231
     232        char *message_buffer = malloc(MESSAGE_BUFFER_SIZE);
     233        if (message_buffer == NULL) {
     234                return;
     235        }
     236
     237        vsnprintf(message_buffer, MESSAGE_BUFFER_SIZE, fmt, args);
     238        logger_message(logger_session, level, message_buffer);
    120239}
    121240
  • uspace/lib/c/include/io/log.h

    rc8444d8 r5882487  
    3636
    3737#include <stdarg.h>
     38#include <bool.h>
    3839
    3940typedef enum {
     
    4950} log_level_t;
    5051
     52extern bool __log_shall_record(log_level_t);
    5153extern int log_init(const char *, log_level_t);
    52 extern void log_msg(log_level_t, const char *, ...);
    53 extern void log_msgv(log_level_t, const char *, va_list);
     54
     55#define log_msg(level, format, ...) \
     56        do { \
     57                if (__log_shall_record((level))) { \
     58                        __log_msg(level, format, ##__VA_ARGS__); \
     59                } \
     60        } while (false)
     61
     62#define log_msgv(level, format, args) \
     63        do { \
     64                if (__log_shall_record((level))) { \
     65                        __log_msgv(level, format, args); \
     66                } \
     67        } while (false)
     68
     69extern void __log_msg(log_level_t, const char *, ...);
     70extern void __log_msgv(log_level_t, const char *, va_list);
    5471
    5572#endif
  • uspace/lib/c/include/ipc/services.h

    rc8444d8 r5882487  
    4545        SERVICE_VFS        = FOURCC('v', 'f', 's', ' '),
    4646        SERVICE_LOC        = FOURCC('l', 'o', 'c', ' '),
     47        SERVICE_LOGGER     = FOURCC('l', 'o', 'g', 'g'),
    4748        SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
    4849        SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
  • uspace/lib/usb/src/debug.c

    rc8444d8 r5882487  
    7474                }
    7575        }
     76        log_init(message_prefix, LVL_DEBUG);
    7677}
    7778
     
    148149        }
    149150
     151        va_start(args, format);
     152        log_msgv(level, format, args);
     153        va_end(args);
     154
    150155        fibril_mutex_unlock(&log_serializer);
    151156}
Note: See TracChangeset for help on using the changeset viewer.