LCOV - code coverage report
Current view: top level - spdk/lib/log - log.c (source / functions) Hit Total Coverage
Test: Combined Lines: 149 181 82.3 %
Date: 2024-12-10 06:07:39 Functions: 15 18 83.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 108 282 38.3 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2016 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : #include "spdk/util.h"
       8                 :            : 
       9                 :            : #include "spdk/log.h"
      10                 :            : 
      11                 :            : static const char *const spdk_level_names[] = {
      12                 :            :         [SPDK_LOG_ERROR]        = "ERROR",
      13                 :            :         [SPDK_LOG_WARN]         = "WARNING",
      14                 :            :         [SPDK_LOG_NOTICE]       = "NOTICE",
      15                 :            :         [SPDK_LOG_INFO]         = "INFO",
      16                 :            :         [SPDK_LOG_DEBUG]        = "DEBUG",
      17                 :            : };
      18                 :            : 
      19                 :            : #define MAX_TMPBUF 1024
      20                 :            : 
      21                 :            : static struct spdk_log_opts g_log_opts = {
      22                 :            :         .log = NULL,
      23                 :            :         .open = NULL,
      24                 :            :         .close = NULL,
      25                 :            :         .user_ctx = NULL,
      26                 :            : };
      27                 :            : static bool g_log_timestamps = true;
      28                 :            : 
      29                 :            : enum spdk_log_level g_spdk_log_level;
      30                 :            : enum spdk_log_level g_spdk_log_print_level;
      31                 :            : 
      32                 :            : void
      33                 :       2354 : spdk_log_set_level(enum spdk_log_level level)
      34                 :            : {
      35   [ +  +  #  # ]:       2354 :         assert(level >= SPDK_LOG_DISABLED);
      36   [ +  +  #  # ]:       2354 :         assert(level <= SPDK_LOG_DEBUG);
      37                 :       2354 :         g_spdk_log_level = level;
      38                 :       2354 : }
      39                 :            : 
      40                 :            : enum spdk_log_level
      41                 :         56 : spdk_log_get_level(void) {
      42                 :         56 :         return g_spdk_log_level;
      43                 :            : }
      44                 :            : 
      45                 :            : void
      46                 :       2387 : spdk_log_set_print_level(enum spdk_log_level level)
      47                 :            : {
      48   [ +  +  #  # ]:       2387 :         assert(level >= SPDK_LOG_DISABLED);
      49   [ +  +  #  # ]:       2387 :         assert(level <= SPDK_LOG_DEBUG);
      50                 :       2387 :         g_spdk_log_print_level = level;
      51                 :       2387 : }
      52                 :            : 
      53                 :            : enum spdk_log_level
      54                 :         20 : spdk_log_get_print_level(void) {
      55                 :         20 :         return g_spdk_log_print_level;
      56                 :            : }
      57                 :            : 
      58                 :            : static void
      59                 :       2338 : log_open(void *ctx)
      60                 :            : {
      61   [ -  +  +  - ]:       2338 :         openlog("spdk", LOG_PID, LOG_LOCAL7);
      62                 :       2338 : }
      63                 :            : 
      64                 :            : static void
      65                 :       2338 : log_close(void *ctx)
      66                 :            : {
      67                 :       2338 :         closelog();
      68                 :       2338 : }
      69                 :            : 
      70                 :            : void
      71                 :       2342 : spdk_log_open(spdk_log_cb *log)
      72                 :            : {
      73         [ +  + ]:       2342 :         if (log) {
      74                 :          4 :                 struct spdk_log_opts opts = {.log = log};
      75                 :          4 :                 opts.size = SPDK_SIZEOF(&opts, log);
      76                 :          4 :                 spdk_log_open_ext(&opts);
      77                 :          1 :         } else {
      78                 :       2338 :                 spdk_log_open_ext(NULL);
      79                 :            :         }
      80                 :       2342 : }
      81                 :            : 
      82                 :            : void
      83                 :       2346 : spdk_log_open_ext(struct spdk_log_opts *opts)
      84                 :            : {
      85         [ +  + ]:       2346 :         if (!opts) {
      86         [ +  - ]:       2338 :                 g_log_opts.open = log_open;
      87         [ +  - ]:       2338 :                 g_log_opts.close = log_close;
      88                 :       2338 :                 goto out;
      89                 :            :         }
      90                 :            : 
      91   [ +  +  #  #  :          8 :         g_log_opts.log = SPDK_GET_FIELD(opts, log, NULL);
          #  #  #  #  #  
                #  #  # ]
      92   [ +  +  #  #  :          8 :         g_log_opts.open = SPDK_GET_FIELD(opts, open, NULL);
          #  #  #  #  #  
                #  #  # ]
      93   [ +  +  #  #  :          8 :         g_log_opts.close = SPDK_GET_FIELD(opts, close, NULL);
          #  #  #  #  #  
                #  #  # ]
      94   [ +  +  #  #  :          8 :         g_log_opts.user_ctx = SPDK_GET_FIELD(opts, user_ctx, NULL);
          #  #  #  #  #  
                #  #  # ]
      95                 :            : 
      96                 :       2230 : out:
      97   [ +  +  +  - ]:       2346 :         if (g_log_opts.open) {
      98   [ +  -  -  +  :       2342 :                 g_log_opts.open(g_log_opts.user_ctx);
             +  -  +  - ]
      99                 :        115 :         }
     100                 :       2346 : }
     101                 :            : 
     102                 :            : void
     103                 :       2368 : spdk_log_close(void)
     104                 :            : {
     105   [ +  +  +  + ]:       2368 :         if (g_log_opts.close) {
     106   [ +  -  -  +  :       2342 :                 g_log_opts.close(g_log_opts.user_ctx);
             +  -  +  - ]
     107                 :        115 :         }
     108         [ +  + ]:       2368 :         memset(&g_log_opts, 0, sizeof(g_log_opts));
     109                 :       2368 : }
     110                 :            : 
     111                 :            : void
     112                 :          0 : spdk_log_enable_timestamps(bool value)
     113                 :            : {
     114         [ #  # ]:          0 :         g_log_timestamps = value;
     115                 :          0 : }
     116                 :            : 
     117                 :            : static void
     118                 :    5984764 : get_timestamp_prefix(char *buf, int buf_size)
     119                 :            : {
     120                 :            :         struct tm *info;
     121                 :      25039 :         char date[24];
     122                 :      25039 :         struct timespec ts;
     123                 :            :         long usec;
     124                 :            : 
     125   [ +  +  +  + ]:    5984764 :         if (!g_log_timestamps) {
     126   [ #  #  #  # ]:          0 :                 buf[0] = '\0';
     127                 :          0 :                 return;
     128                 :            :         }
     129                 :            : 
     130         [ +  + ]:    5984764 :         clock_gettime(CLOCK_REALTIME, &ts);
     131                 :    5984764 :         info = localtime(&ts.tv_sec);
     132   [ +  -  +  - ]:    5984764 :         usec = ts.tv_nsec / 1000;
     133         [ +  + ]:    5984764 :         if (info == NULL) {
     134         [ #  # ]:          0 :                 snprintf(buf, buf_size, "[%s.%06ld] ", "unknown date", usec);
     135                 :          0 :                 return;
     136                 :            :         }
     137                 :            : 
     138   [ -  +  -  +  :    5984764 :         strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", info);
                   -  + ]
     139         [ -  + ]:    5984764 :         snprintf(buf, buf_size, "[%s.%06ld] ", date, usec);
     140                 :       6506 : }
     141                 :            : 
     142                 :            : void
     143                 :    6703800 : spdk_log(enum spdk_log_level level, const char *file, const int line, const char *func,
     144                 :            :          const char *format, ...)
     145                 :            : {
     146                 :      33651 :         va_list ap;
     147                 :            : 
     148                 :    6703800 :         va_start(ap, format);
     149                 :    6703800 :         spdk_vlog(level, file, line, func, format, ap);
     150                 :    6703800 :         va_end(ap);
     151                 :    6703800 : }
     152                 :            : 
     153                 :            : int
     154                 :    5984800 : spdk_log_to_syslog_level(enum spdk_log_level level)
     155                 :            : {
     156   [ +  +  +  +  :    5984800 :         switch (level) {
                   -  + ]
     157                 :      30015 :         case SPDK_LOG_DEBUG:
     158                 :            :         case SPDK_LOG_INFO:
     159                 :      30016 :                 return LOG_INFO;
     160                 :    2576206 :         case SPDK_LOG_NOTICE:
     161                 :    2580959 :                 return LOG_NOTICE;
     162                 :        339 :         case SPDK_LOG_WARN:
     163                 :        373 :                 return LOG_WARNING;
     164                 :    3371720 :         case SPDK_LOG_ERROR:
     165                 :    3373452 :                 return LOG_ERR;
     166                 :          0 :         case SPDK_LOG_DISABLED:
     167                 :          0 :                 return -1;
     168                 :          0 :         default:
     169                 :          0 :                 break;
     170                 :            :         }
     171                 :            : 
     172                 :          0 :         return LOG_INFO;
     173                 :       6520 : }
     174                 :            : 
     175                 :            : void
     176                 :    6704956 : spdk_vlog(enum spdk_log_level level, const char *file, const int line, const char *func,
     177                 :            :           const char *format, va_list ap)
     178                 :            : {
     179                 :    6704956 :         int severity = LOG_INFO;
     180                 :    6704956 :         char *buf, _buf[MAX_TMPBUF], *ext_buf = NULL;
     181                 :      33651 :         char timestamp[64];
     182                 :      33651 :         va_list ap_copy;
     183                 :            :         int rc;
     184                 :            : 
     185   [ +  +  -  + ]:    6704956 :         if (g_log_opts.log) {
     186   [ #  #  #  #  :         24 :                 g_log_opts.log(level, file, line, func, format, ap);
                   #  # ]
     187                 :     710216 :                 return;
     188                 :            :         }
     189                 :            : 
     190   [ +  +  +  + ]:    6704932 :         if (level > g_spdk_log_print_level && level > g_spdk_log_level) {
     191                 :     720168 :                 return;
     192                 :            :         }
     193                 :            : 
     194                 :    5984764 :         severity = spdk_log_to_syslog_level(level);
     195         [ +  + ]:    5984764 :         if (severity < 0) {
     196                 :          0 :                 return;
     197                 :            :         }
     198                 :            : 
     199                 :    5984764 :         buf = _buf;
     200                 :            : 
     201                 :    5984764 :         va_copy(ap_copy, ap);
     202         [ -  + ]:    5984764 :         rc = vsnprintf(_buf, sizeof(_buf), format, ap);
     203         [ +  + ]:    5984764 :         if (rc > MAX_TMPBUF) {
     204                 :            :                 /* The output including the terminating was more than MAX_TMPBUF bytes.
     205                 :            :                  * Try allocating memory large enough to hold the output.
     206                 :            :                  */
     207                 :          3 :                 rc = vasprintf(&ext_buf, format, ap_copy);
     208         [ +  - ]:          3 :                 if (rc < 0) {
     209                 :            :                         /* Failed to allocate memory. Allow output to be truncated. */
     210                 :          0 :                 } else {
     211                 :          3 :                         buf = ext_buf;
     212                 :            :                 }
     213                 :          0 :         }
     214                 :    5984764 :         va_end(ap_copy);
     215                 :            : 
     216         [ +  + ]:    5984764 :         if (level <= g_spdk_log_print_level) {
     217                 :    5984764 :                 get_timestamp_prefix(timestamp, sizeof(timestamp));
     218         [ +  + ]:    5984764 :                 if (file) {
     219   [ -  +  -  +  :    5979220 :                         fprintf(stderr, "%s%s:%4d:%s: *%s*: %s", timestamp, file, line, func, spdk_level_names[level], buf);
                   -  + ]
     220                 :       6286 :                 } else {
     221   [ -  +  -  + ]:       5544 :                         fprintf(stderr, "%s%s", timestamp, buf);
     222                 :            :                 }
     223                 :       6506 :         }
     224                 :            : 
     225         [ +  + ]:    5984764 :         if (level <= g_spdk_log_level) {
     226         [ +  + ]:    5953903 :                 if (file) {
     227   [ -  +  -  +  :    5949361 :                         syslog(severity, "%s:%4d:%s: *%s*: %s", file, line, func, spdk_level_names[level], buf);
                   -  + ]
     228                 :       6286 :                 } else {
     229                 :       4542 :                         syslog(severity, "%s", buf);
     230                 :            :                 }
     231                 :       6506 :         }
     232                 :            : 
     233                 :    5984764 :         free(ext_buf);
     234                 :       7894 : }
     235                 :            : 
     236                 :            : void
     237                 :          0 : spdk_vflog(FILE *fp, const char *file, const int line, const char *func,
     238                 :            :            const char *format, va_list ap)
     239                 :            : {
     240                 :          0 :         char buf[MAX_TMPBUF];
     241                 :          0 :         char timestamp[64];
     242                 :            : 
     243         [ #  # ]:          0 :         vsnprintf(buf, sizeof(buf), format, ap);
     244                 :            : 
     245                 :          0 :         get_timestamp_prefix(timestamp, sizeof(timestamp));
     246                 :            : 
     247         [ #  # ]:          0 :         if (file) {
     248   [ #  #  #  # ]:          0 :                 fprintf(fp, "%s%s:%4d:%s: %s", timestamp, file, line, func, buf);
     249                 :          0 :         } else {
     250   [ #  #  #  # ]:          0 :                 fprintf(fp, "%s%s", timestamp, buf);
     251                 :            :         }
     252                 :            : 
     253                 :          0 :         fflush(fp);
     254                 :          0 : }
     255                 :            : 
     256                 :            : void
     257                 :          0 : spdk_flog(FILE *fp, const char *file, const int line, const char *func,
     258                 :            :           const char *format, ...)
     259                 :            : {
     260                 :          0 :         va_list ap;
     261                 :            : 
     262                 :          0 :         va_start(ap, format);
     263                 :          0 :         spdk_vflog(fp, file, line, func, format, ap);
     264                 :          0 :         va_end(ap);
     265                 :          0 : }
     266                 :            : 
     267                 :            : static void
     268                 :       5839 : fdump(FILE *fp, const char *label, const uint8_t *buf, size_t len)
     269                 :            : {
     270                 :         12 :         char tmpbuf[MAX_TMPBUF];
     271                 :         12 :         char buf16[16 + 1];
     272                 :            :         size_t total;
     273                 :            :         unsigned int idx;
     274                 :            : 
     275         [ -  + ]:       5839 :         fprintf(fp, "%s\n", label);
     276                 :            : 
     277         [ #  # ]:       5839 :         memset(buf16, 0, sizeof buf16);
     278                 :       5839 :         total = 0;
     279         [ +  + ]:    4358482 :         for (idx = 0; idx < len; idx++) {
     280   [ +  +  +  +  :    4352643 :                 if (idx != 0 && idx % 16 == 0) {
                   #  # ]
     281   [ #  #  #  # ]:     266209 :                         snprintf(tmpbuf + total, sizeof tmpbuf - total,
     282                 :          1 :                                  " %s", buf16);
     283         [ #  # ]:     266208 :                         memset(buf16, 0, sizeof buf16);
     284         [ -  + ]:     266208 :                         fprintf(fp, "%s\n", tmpbuf);
     285                 :     266208 :                         total = 0;
     286                 :          1 :                 }
     287   [ +  +  #  # ]:    4352643 :                 if (idx % 16 == 0) {
     288   [ #  #  #  # ]:     272051 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     289                 :          4 :                                           "%08x ", idx);
     290                 :          4 :                 }
     291   [ +  +  #  # ]:    4352643 :                 if (idx % 8 == 0) {
     292   [ #  #  #  # ]:     544085 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     293                 :            :                                           "%s", " ");
     294                 :          6 :                 }
     295   [ #  #  #  # ]:    8705246 :                 total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     296   [ #  #  #  # ]:    4352643 :                                   "%2.2x ", buf[idx] & 0xff);
     297   [ +  +  #  #  :    4352643 :                 buf16[idx % 16] = isprint(buf[idx]) ? buf[idx] : '.';
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     298                 :         40 :         }
     299   [ +  +  #  # ]:       5948 :         for (; idx % 16 != 0; idx++) {
     300         [ +  + ]:        109 :                 if (idx == 8) {
     301   [ #  #  #  # ]:          5 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     302                 :            :                                           " ");
     303                 :          1 :                 }
     304                 :            : 
     305   [ #  #  #  # ]:        109 :                 total += snprintf(tmpbuf + total, sizeof tmpbuf - total, "   ");
     306                 :         24 :         }
     307   [ #  #  #  # ]:       5839 :         snprintf(tmpbuf + total, sizeof tmpbuf - total, "  %s", buf16);
     308         [ -  + ]:       5839 :         fprintf(fp, "%s\n", tmpbuf);
     309                 :       5839 :         fflush(fp);
     310                 :       5839 : }
     311                 :            : 
     312                 :            : void
     313                 :       5839 : spdk_log_dump(FILE *fp, const char *label, const void *buf, size_t len)
     314                 :            : {
     315                 :       5839 :         fdump(fp, label, buf, len);
     316                 :       5839 : }

Generated by: LCOV version 1.14