LCOV - code coverage report
Current view: top level - lib/log - log.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 105 138 76.1 %
Date: 2024-11-20 23:57:33 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        1277 : get_timestamp_prefix(char *buf, int buf_size)
      78             : {
      79             :         struct tm *info;
      80        1277 :         char date[24];
      81        1277 :         struct timespec ts;
      82             :         long usec;
      83             : 
      84        1277 :         if (!g_log_timestamps) {
      85           0 :                 buf[0] = '\0';
      86           0 :                 return;
      87             :         }
      88             : 
      89        1277 :         clock_gettime(CLOCK_REALTIME, &ts);
      90        1277 :         info = localtime(&ts.tv_sec);
      91        1277 :         usec = ts.tv_nsec / 1000;
      92        1277 :         if (info == NULL) {
      93           0 :                 snprintf(buf, buf_size, "[%s.%06ld] ", "unknown date", usec);
      94           0 :                 return;
      95             :         }
      96             : 
      97        1277 :         strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", info);
      98        1277 :         snprintf(buf, buf_size, "[%s.%06ld] ", date, usec);
      99             : }
     100             : 
     101             : void
     102        2505 : spdk_log(enum spdk_log_level level, const char *file, const int line, const char *func,
     103             :          const char *format, ...)
     104             : {
     105        2505 :         va_list ap;
     106             : 
     107        2505 :         va_start(ap, format);
     108        2505 :         spdk_vlog(level, file, line, func, format, ap);
     109        2505 :         va_end(ap);
     110        2505 : }
     111             : 
     112             : int
     113        1277 : spdk_log_to_syslog_level(enum spdk_log_level level)
     114             : {
     115        1277 :         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        1275 :         case SPDK_LOG_ERROR:
     124        1275 :                 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        2505 : 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        2505 :         int severity = LOG_INFO;
     139        2505 :         char *buf, _buf[MAX_TMPBUF], *ext_buf = NULL;
     140        2505 :         char timestamp[64];
     141        2505 :         va_list ap_copy;
     142             :         int rc;
     143             : 
     144        2505 :         if (g_log) {
     145           5 :                 g_log(level, file, line, func, format, ap);
     146           5 :                 return;
     147             :         }
     148             : 
     149        2500 :         if (level > g_spdk_log_print_level && level > g_spdk_log_level) {
     150        1223 :                 return;
     151             :         }
     152             : 
     153        1277 :         severity = spdk_log_to_syslog_level(level);
     154        1277 :         if (severity < 0) {
     155           0 :                 return;
     156             :         }
     157             : 
     158        1277 :         buf = _buf;
     159             : 
     160        1277 :         va_copy(ap_copy, ap);
     161        1277 :         rc = vsnprintf(_buf, sizeof(_buf), format, ap);
     162        1277 :         if (rc > MAX_TMPBUF) {
     163             :                 /* The output including the terminating was more than MAX_TMPBUF bytes.
     164             :                  * Try allocating memory large enough to hold the output.
     165             :                  */
     166           1 :                 rc = vasprintf(&ext_buf, format, ap_copy);
     167           1 :                 if (rc < 0) {
     168             :                         /* Failed to allocate memory. Allow output to be truncated. */
     169             :                 } else {
     170           1 :                         buf = ext_buf;
     171             :                 }
     172             :         }
     173        1277 :         va_end(ap_copy);
     174             : 
     175        1277 :         if (level <= g_spdk_log_print_level) {
     176        1277 :                 get_timestamp_prefix(timestamp, sizeof(timestamp));
     177        1277 :                 if (file) {
     178        1277 :                         fprintf(stderr, "%s%s:%4d:%s: *%s*: %s", timestamp, file, line, func, spdk_level_names[level], buf);
     179             :                 } else {
     180           0 :                         fprintf(stderr, "%s%s", timestamp, buf);
     181             :                 }
     182             :         }
     183             : 
     184        1277 :         if (level <= g_spdk_log_level) {
     185        1277 :                 if (file) {
     186        1277 :                         syslog(severity, "%s:%4d:%s: *%s*: %s", file, line, func, spdk_level_names[level], buf);
     187             :                 } else {
     188           0 :                         syslog(severity, "%s", buf);
     189             :                 }
     190             :         }
     191             : 
     192        1277 :         free(ext_buf);
     193             : }
     194             : 
     195             : void
     196           0 : spdk_vflog(FILE *fp, const char *file, const int line, const char *func,
     197             :            const char *format, va_list ap)
     198             : {
     199           0 :         char buf[MAX_TMPBUF];
     200           0 :         char timestamp[64];
     201             : 
     202           0 :         vsnprintf(buf, sizeof(buf), format, ap);
     203             : 
     204           0 :         get_timestamp_prefix(timestamp, sizeof(timestamp));
     205             : 
     206           0 :         if (file) {
     207           0 :                 fprintf(fp, "%s%s:%4d:%s: %s", timestamp, file, line, func, buf);
     208             :         } else {
     209           0 :                 fprintf(fp, "%s%s", timestamp, buf);
     210             :         }
     211             : 
     212           0 :         fflush(fp);
     213           0 : }
     214             : 
     215             : void
     216           0 : spdk_flog(FILE *fp, const char *file, const int line, const char *func,
     217             :           const char *format, ...)
     218             : {
     219           0 :         va_list ap;
     220             : 
     221           0 :         va_start(ap, format);
     222           0 :         spdk_vflog(fp, file, line, func, format, ap);
     223           0 :         va_end(ap);
     224           0 : }
     225             : 
     226             : static void
     227           3 : fdump(FILE *fp, const char *label, const uint8_t *buf, size_t len)
     228             : {
     229           3 :         char tmpbuf[MAX_TMPBUF];
     230           3 :         char buf16[16 + 1];
     231             :         size_t total;
     232             :         unsigned int idx;
     233             : 
     234           3 :         fprintf(fp, "%s\n", label);
     235             : 
     236           3 :         memset(buf16, 0, sizeof buf16);
     237           3 :         total = 0;
     238          43 :         for (idx = 0; idx < len; idx++) {
     239          40 :                 if (idx != 0 && idx % 16 == 0) {
     240           1 :                         snprintf(tmpbuf + total, sizeof tmpbuf - total,
     241             :                                  " %s", buf16);
     242           1 :                         memset(buf16, 0, sizeof buf16);
     243           1 :                         fprintf(fp, "%s\n", tmpbuf);
     244           1 :                         total = 0;
     245             :                 }
     246          40 :                 if (idx % 16 == 0) {
     247           4 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     248             :                                           "%08x ", idx);
     249             :                 }
     250          40 :                 if (idx % 8 == 0) {
     251           6 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     252             :                                           "%s", " ");
     253             :                 }
     254          40 :                 total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     255          40 :                                   "%2.2x ", buf[idx] & 0xff);
     256          40 :                 buf16[idx % 16] = isprint(buf[idx]) ? buf[idx] : '.';
     257             :         }
     258          27 :         for (; idx % 16 != 0; idx++) {
     259          24 :                 if (idx == 8) {
     260           1 :                         total += snprintf(tmpbuf + total, sizeof tmpbuf - total,
     261             :                                           " ");
     262             :                 }
     263             : 
     264          24 :                 total += snprintf(tmpbuf + total, sizeof tmpbuf - total, "   ");
     265             :         }
     266           3 :         snprintf(tmpbuf + total, sizeof tmpbuf - total, "  %s", buf16);
     267           3 :         fprintf(fp, "%s\n", tmpbuf);
     268           3 :         fflush(fp);
     269           3 : }
     270             : 
     271             : void
     272           3 : spdk_log_dump(FILE *fp, const char *label, const void *buf, size_t len)
     273             : {
     274           3 :         fdump(fp, label, buf, len);
     275           3 : }

Generated by: LCOV version 1.15