LCOV - code coverage report
Current view: top level - lib/log - log.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 102 135 75.6 %
Date: 2024-07-15 10:53:15 Functions: 12 15 80.0 %

          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             : 
       8             : #include "spdk/log.h"
       9             : 
      10             : static const char *const spdk_level_names[] = {
      11             :         [SPDK_LOG_ERROR]        = "ERROR",
      12             :         [SPDK_LOG_WARN]         = "WARNING",
      13             :         [SPDK_LOG_NOTICE]       = "NOTICE",
      14             :         [SPDK_LOG_INFO]         = "INFO",
      15             :         [SPDK_LOG_DEBUG]        = "DEBUG",
      16             : };
      17             : 
      18             : #define MAX_TMPBUF 1024
      19             : 
      20             : static logfunc *g_log = NULL;
      21             : static bool g_log_timestamps = true;
      22             : 
      23             : enum spdk_log_level g_spdk_log_level;
      24             : enum spdk_log_level g_spdk_log_print_level;
      25             : 
      26             : void
      27           5 : spdk_log_set_level(enum spdk_log_level level)
      28             : {
      29           5 :         assert(level >= SPDK_LOG_DISABLED);
      30           5 :         assert(level <= SPDK_LOG_DEBUG);
      31           5 :         g_spdk_log_level = level;
      32           5 : }
      33             : 
      34             : enum spdk_log_level
      35           5 : spdk_log_get_level(void) {
      36           5 :         return g_spdk_log_level;
      37             : }
      38             : 
      39             : void
      40           5 : spdk_log_set_print_level(enum spdk_log_level level)
      41             : {
      42           5 :         assert(level >= SPDK_LOG_DISABLED);
      43           5 :         assert(level <= SPDK_LOG_DEBUG);
      44           5 :         g_spdk_log_print_level = level;
      45           5 : }
      46             : 
      47             : enum spdk_log_level
      48           5 : spdk_log_get_print_level(void) {
      49           5 :         return g_spdk_log_print_level;
      50             : }
      51             : 
      52             : void
      53           2 : spdk_log_open(logfunc *logf)
      54             : {
      55           2 :         if (logf) {
      56           1 :                 g_log = logf;
      57             :         } else {
      58           1 :                 openlog("spdk", LOG_PID, LOG_LOCAL7);
      59             :         }
      60           2 : }
      61             : 
      62             : void
      63           1 : spdk_log_close(void)
      64             : {
      65           1 :         if (!g_log) {
      66           1 :                 closelog();
      67             :         }
      68           1 : }
      69             : 
      70             : void
      71           0 : spdk_log_enable_timestamps(bool value)
      72             : {
      73           0 :         g_log_timestamps = value;
      74           0 : }
      75             : 
      76             : static void
      77        1252 : get_timestamp_prefix(char *buf, int buf_size)
      78             : {
      79             :         struct tm *info;
      80        1252 :         char date[24];
      81        1252 :         struct timespec ts;
      82             :         long usec;
      83             : 
      84        1252 :         if (!g_log_timestamps) {
      85           0 :                 buf[0] = '\0';
      86           0 :                 return;
      87             :         }
      88             : 
      89        1252 :         clock_gettime(CLOCK_REALTIME, &ts);
      90        1252 :         info = localtime(&ts.tv_sec);
      91        1252 :         usec = ts.tv_nsec / 1000;
      92        1252 :         if (info == NULL) {
      93           0 :                 snprintf(buf, buf_size, "[%s.%06ld] ", "unknown date", usec);
      94           0 :                 return;
      95             :         }
      96             : 
      97        1252 :         strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", info);
      98        1252 :         snprintf(buf, buf_size, "[%s.%06ld] ", date, usec);
      99             : }
     100             : 
     101             : void
     102        2476 : spdk_log(enum spdk_log_level level, const char *file, const int line, const char *func,
     103             :          const char *format, ...)
     104             : {
     105        2476 :         va_list ap;
     106             : 
     107        2476 :         va_start(ap, format);
     108        2476 :         spdk_vlog(level, file, line, func, format, ap);
     109        2476 :         va_end(ap);
     110        2476 : }
     111             : 
     112             : int
     113        1252 : spdk_log_to_syslog_level(enum spdk_log_level level)
     114             : {
     115        1252 :         switch (level) {
     116           1 :         case SPDK_LOG_DEBUG:
     117             :         case SPDK_LOG_INFO:
     118           1 :                 return LOG_INFO;
     119           0 :         case SPDK_LOG_NOTICE:
     120           0 :                 return LOG_NOTICE;
     121           1 :         case SPDK_LOG_WARN:
     122           1 :                 return LOG_WARNING;
     123        1250 :         case SPDK_LOG_ERROR:
     124        1250 :                 return LOG_ERR;
     125           0 :         case SPDK_LOG_DISABLED:
     126           0 :                 return -1;
     127           0 :         default:
     128           0 :                 break;
     129             :         }
     130             : 
     131           0 :         return LOG_INFO;
     132             : }
     133             : 
     134             : void
     135        2476 : spdk_vlog(enum spdk_log_level level, const char *file, const int line, const char *func,
     136             :           const char *format, va_list ap)
     137             : {
     138        2476 :         int severity = LOG_INFO;
     139        2476 :         char *buf, _buf[MAX_TMPBUF], *ext_buf = NULL;
     140        2476 :         char timestamp[64];
     141             :         int rc;
     142             : 
     143        2476 :         if (g_log) {
     144           5 :                 g_log(level, file, line, func, format, ap);
     145           5 :                 return;
     146             :         }
     147             : 
     148        2471 :         if (level > g_spdk_log_print_level && level > g_spdk_log_level) {
     149        1219 :                 return;
     150             :         }
     151             : 
     152        1252 :         severity = spdk_log_to_syslog_level(level);
     153        1252 :         if (severity < 0) {
     154           0 :                 return;
     155             :         }
     156             : 
     157        1252 :         buf = _buf;
     158             : 
     159        1252 :         rc = vsnprintf(_buf, sizeof(_buf), format, ap);
     160        1252 :         if (rc > MAX_TMPBUF) {
     161             :                 /* The output including the terminating was more than MAX_TMPBUF bytes.
     162             :                  * Try allocating memory large enough to hold the output.
     163             :                  */
     164           1 :                 rc = vasprintf(&ext_buf, format, ap);
     165           1 :                 if (rc < 0) {
     166             :                         /* Failed to allocate memory. Allow output to be truncated. */
     167             :                 } else {
     168           1 :                         buf = ext_buf;
     169             :                 }
     170             :         }
     171             : 
     172        1252 :         if (level <= g_spdk_log_print_level) {
     173        1252 :                 get_timestamp_prefix(timestamp, sizeof(timestamp));
     174        1252 :                 if (file) {
     175        1252 :                         fprintf(stderr, "%s%s:%4d:%s: *%s*: %s", timestamp, file, line, func, spdk_level_names[level], buf);
     176             :                 } else {
     177           0 :                         fprintf(stderr, "%s%s", timestamp, buf);
     178             :                 }
     179             :         }
     180             : 
     181        1252 :         if (level <= g_spdk_log_level) {
     182        1252 :                 if (file) {
     183        1252 :                         syslog(severity, "%s:%4d:%s: *%s*: %s", file, line, func, spdk_level_names[level], buf);
     184             :                 } else {
     185           0 :                         syslog(severity, "%s", buf);
     186             :                 }
     187             :         }
     188             : 
     189        1252 :         free(ext_buf);
     190             : }
     191             : 
     192             : void
     193           0 : spdk_vflog(FILE *fp, const char *file, const int line, const char *func,
     194             :            const char *format, va_list ap)
     195             : {
     196           0 :         char buf[MAX_TMPBUF];
     197           0 :         char timestamp[64];
     198             : 
     199           0 :         vsnprintf(buf, sizeof(buf), format, ap);
     200             : 
     201           0 :         get_timestamp_prefix(timestamp, sizeof(timestamp));
     202             : 
     203           0 :         if (file) {
     204           0 :                 fprintf(fp, "%s%s:%4d:%s: %s", timestamp, file, line, func, buf);
     205             :         } else {
     206           0 :                 fprintf(fp, "%s%s", timestamp, buf);
     207             :         }
     208             : 
     209           0 :         fflush(fp);
     210           0 : }
     211             : 
     212             : void
     213           0 : spdk_flog(FILE *fp, const char *file, const int line, const char *func,
     214             :           const char *format, ...)
     215             : {
     216           0 :         va_list ap;
     217             : 
     218           0 :         va_start(ap, format);
     219           0 :         spdk_vflog(fp, file, line, func, format, ap);
     220           0 :         va_end(ap);
     221           0 : }
     222             : 
     223             : static void
     224           3 : fdump(FILE *fp, const char *label, const uint8_t *buf, size_t len)
     225             : {
     226           3 :         char tmpbuf[MAX_TMPBUF];
     227           3 :         char buf16[16 + 1];
     228             :         size_t total;
     229             :         unsigned int idx;
     230             : 
     231           3 :         fprintf(fp, "%s\n", label);
     232             : 
     233           3 :         memset(buf16, 0, sizeof buf16);
     234           3 :         total = 0;
     235          43 :         for (idx = 0; idx < len; idx++) {
     236          40 :                 if (idx != 0 && idx % 16 == 0) {
     237           1 :                         snprintf(tmpbuf + total, sizeof tmpbuf - total,
     238             :                                  " %s", buf16);
     239           1 :                         memset(buf16, 0, sizeof buf16);
     240           1 :                         fprintf(fp, "%s\n", tmpbuf);
     241           1 :                         total = 0;
     242             :                 }
     243          40 :                 if (idx % 16 == 0) {
     244           4 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     245             :                                           "%08x ", idx);
     246             :                 }
     247          40 :                 if (idx % 8 == 0) {
     248           6 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     249             :                                           "%s", " ");
     250             :                 }
     251          40 :                 total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     252          40 :                                   "%2.2x ", buf[idx] & 0xff);
     253          40 :                 buf16[idx % 16] = isprint(buf[idx]) ? buf[idx] : '.';
     254             :         }
     255          27 :         for (; idx % 16 != 0; idx++) {
     256          24 :                 if (idx == 8) {
     257           1 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     258             :                                           " ");
     259             :                 }
     260             : 
     261          24 :                 total += snprintf(tmpbuf + total, sizeof tmpbuf - total, "   ");
     262             :         }
     263           3 :         snprintf(tmpbuf + total, sizeof tmpbuf - total, "  %s", buf16);
     264           3 :         fprintf(fp, "%s\n", tmpbuf);
     265           3 :         fflush(fp);
     266           3 : }
     267             : 
     268             : void
     269           3 : spdk_log_dump(FILE *fp, const char *label, const void *buf, size_t len)
     270             : {
     271           3 :         fdump(fp, label, buf, len);
     272           3 : }

Generated by: LCOV version 1.15