LCOV - differential code coverage report
Current view: top level - src/common - logging.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 71.4 % 133 95 38 95
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 8 8 8
Baseline: 16@8cea358b128 Branches: 48.3 % 87 42 45 42
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 71.4 % 133 95 38 95
Function coverage date bins:
(240..) days: 100.0 % 8 8 8
Branch coverage date bins:
(240..) days: 48.3 % 87 42 45 42

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  * Logging framework for frontend programs
                                  3                 :                :  *
                                  4                 :                :  * Copyright (c) 2018-2024, PostgreSQL Global Development Group
                                  5                 :                :  *
                                  6                 :                :  * src/common/logging.c
                                  7                 :                :  *
                                  8                 :                :  *-------------------------------------------------------------------------
                                  9                 :                :  */
                                 10                 :                : 
                                 11                 :                : #ifndef FRONTEND
                                 12                 :                : #error "This file is not expected to be compiled for backend code"
                                 13                 :                : #endif
                                 14                 :                : 
                                 15                 :                : #include "postgres_fe.h"
                                 16                 :                : 
                                 17                 :                : #include <unistd.h>
                                 18                 :                : 
                                 19                 :                : #include "common/logging.h"
                                 20                 :                : 
                                 21                 :                : enum pg_log_level __pg_log_level;
                                 22                 :                : 
                                 23                 :                : static const char *progname;
                                 24                 :                : static int  log_flags;
                                 25                 :                : 
                                 26                 :                : static void (*log_pre_callback) (void);
                                 27                 :                : static void (*log_locus_callback) (const char **, uint64 *);
                                 28                 :                : 
                                 29                 :                : static const char *sgr_error = NULL;
                                 30                 :                : static const char *sgr_warning = NULL;
                                 31                 :                : static const char *sgr_note = NULL;
                                 32                 :                : static const char *sgr_locus = NULL;
                                 33                 :                : 
                                 34                 :                : #define SGR_ERROR_DEFAULT "01;31"
                                 35                 :                : #define SGR_WARNING_DEFAULT "01;35"
                                 36                 :                : #define SGR_NOTE_DEFAULT "01;36"
                                 37                 :                : #define SGR_LOCUS_DEFAULT "01"
                                 38                 :                : 
                                 39                 :                : #define ANSI_ESCAPE_FMT "\x1b[%sm"
                                 40                 :                : #define ANSI_ESCAPE_RESET "\x1b[0m"
                                 41                 :                : 
                                 42                 :                : #ifdef WIN32
                                 43                 :                : 
                                 44                 :                : #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
                                 45                 :                : #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
                                 46                 :                : #endif
                                 47                 :                : 
                                 48                 :                : /*
                                 49                 :                :  * Attempt to enable VT100 sequence processing for colorization on Windows.
                                 50                 :                :  * If current environment is not VT100-compatible or if this mode could not
                                 51                 :                :  * be enabled, return false.
                                 52                 :                :  */
                                 53                 :                : static bool
                                 54                 :                : enable_vt_processing(void)
                                 55                 :                : {
                                 56                 :                :     /* Check stderr */
                                 57                 :                :     HANDLE      hOut = GetStdHandle(STD_ERROR_HANDLE);
                                 58                 :                :     DWORD       dwMode = 0;
                                 59                 :                : 
                                 60                 :                :     if (hOut == INVALID_HANDLE_VALUE)
                                 61                 :                :         return false;
                                 62                 :                : 
                                 63                 :                :     /*
                                 64                 :                :      * Look for the current console settings and check if VT100 is already
                                 65                 :                :      * enabled.
                                 66                 :                :      */
                                 67                 :                :     if (!GetConsoleMode(hOut, &dwMode))
                                 68                 :                :         return false;
                                 69                 :                :     if ((dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0)
                                 70                 :                :         return true;
                                 71                 :                : 
                                 72                 :                :     dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
                                 73                 :                :     if (!SetConsoleMode(hOut, dwMode))
                                 74                 :                :         return false;
                                 75                 :                :     return true;
                                 76                 :                : }
                                 77                 :                : #endif                          /* WIN32 */
                                 78                 :                : 
                                 79                 :                : /*
                                 80                 :                :  * This should be called before any output happens.
                                 81                 :                :  */
                                 82                 :                : void
 1840 peter@eisentraut.org       83                 :CBC       11778 : pg_logging_init(const char *argv0)
                                 84                 :                : {
                                 85                 :          11778 :     const char *pg_color_env = getenv("PG_COLOR");
                                 86                 :          11778 :     bool        log_color = false;
 1504 michael@paquier.xyz        87                 :          11778 :     bool        color_terminal = isatty(fileno(stderr));
                                 88                 :                : 
                                 89                 :                : #ifdef WIN32
                                 90                 :                : 
                                 91                 :                :     /*
                                 92                 :                :      * On Windows, check if environment is VT100-compatible if using a
                                 93                 :                :      * terminal.
                                 94                 :                :      */
                                 95                 :                :     if (color_terminal)
                                 96                 :                :         color_terminal = enable_vt_processing();
                                 97                 :                : #endif
                                 98                 :                : 
                                 99                 :                :     /* usually the default, but not on Windows */
 1840 peter@eisentraut.org      100                 :          11778 :     setvbuf(stderr, NULL, _IONBF, 0);
                                101                 :                : 
                                102                 :          11778 :     progname = get_progname(argv0);
                                103                 :          11778 :     __pg_log_level = PG_LOG_INFO;
                                104                 :                : 
                                105         [ -  + ]:          11778 :     if (pg_color_env)
                                106                 :                :     {
 1840 peter@eisentraut.org      107         [ #  # ]:UBC           0 :         if (strcmp(pg_color_env, "always") == 0 ||
 1504 michael@paquier.xyz       108   [ #  #  #  # ]:              0 :             (strcmp(pg_color_env, "auto") == 0 && color_terminal))
 1840 peter@eisentraut.org      109                 :              0 :             log_color = true;
                                110                 :                :     }
                                111                 :                : 
 1840 peter@eisentraut.org      112         [ -  + ]:CBC       11778 :     if (log_color)
                                113                 :                :     {
 1840 peter@eisentraut.org      114                 :UBC           0 :         const char *pg_colors_env = getenv("PG_COLORS");
                                115                 :                : 
                                116         [ #  # ]:              0 :         if (pg_colors_env)
                                117                 :                :         {
 1789 tgl@sss.pgh.pa.us         118                 :              0 :             char       *colors = strdup(pg_colors_env);
                                119                 :                : 
 1840 peter@eisentraut.org      120         [ #  # ]:              0 :             if (colors)
                                121                 :                :             {
                                122         [ #  # ]:              0 :                 for (char *token = strtok(colors, ":"); token; token = strtok(NULL, ":"))
                                123                 :                :                 {
 1789 tgl@sss.pgh.pa.us         124                 :              0 :                     char       *e = strchr(token, '=');
                                125                 :                : 
 1840 peter@eisentraut.org      126         [ #  # ]:              0 :                     if (e)
                                127                 :                :                     {
                                128                 :                :                         char       *name;
                                129                 :                :                         char       *value;
                                130                 :                : 
                                131                 :              0 :                         *e = '\0';
                                132                 :              0 :                         name = token;
                                133                 :              0 :                         value = e + 1;
                                134                 :                : 
                                135         [ #  # ]:              0 :                         if (strcmp(name, "error") == 0)
                                136                 :              0 :                             sgr_error = strdup(value);
                                137         [ #  # ]:              0 :                         if (strcmp(name, "warning") == 0)
                                138                 :              0 :                             sgr_warning = strdup(value);
  734                           139         [ #  # ]:              0 :                         if (strcmp(name, "note") == 0)
                                140                 :              0 :                             sgr_note = strdup(value);
 1840                           141         [ #  # ]:              0 :                         if (strcmp(name, "locus") == 0)
                                142                 :              0 :                             sgr_locus = strdup(value);
                                143                 :                :                     }
                                144                 :                :                 }
                                145                 :                : 
                                146                 :              0 :                 free(colors);
                                147                 :                :             }
                                148                 :                :         }
                                149                 :                :         else
                                150                 :                :         {
                                151                 :              0 :             sgr_error = SGR_ERROR_DEFAULT;
                                152                 :              0 :             sgr_warning = SGR_WARNING_DEFAULT;
  734                           153                 :              0 :             sgr_note = SGR_NOTE_DEFAULT;
 1840                           154                 :              0 :             sgr_locus = SGR_LOCUS_DEFAULT;
                                155                 :                :         }
                                156                 :                :     }
 1840 peter@eisentraut.org      157                 :CBC       11778 : }
                                158                 :                : 
                                159                 :                : /*
                                160                 :                :  * Change the logging flags.
                                161                 :                :  */
                                162                 :                : void
                                163                 :          16050 : pg_logging_config(int new_flags)
                                164                 :                : {
                                165                 :          16050 :     log_flags = new_flags;
                                166                 :          16050 : }
                                167                 :                : 
                                168                 :                : /*
                                169                 :                :  * pg_logging_init sets the default log level to INFO.  Programs that prefer
                                170                 :                :  * a different default should use this to set it, immediately afterward.
                                171                 :                :  */
                                172                 :                : void
                                173                 :            379 : pg_logging_set_level(enum pg_log_level new_level)
                                174                 :                : {
                                175                 :            379 :     __pg_log_level = new_level;
                                176                 :            379 : }
                                177                 :                : 
                                178                 :                : /*
                                179                 :                :  * Command line switches such as --verbose should invoke this.
                                180                 :                :  */
                                181                 :                : void
 1305 tgl@sss.pgh.pa.us         182                 :             66 : pg_logging_increase_verbosity(void)
                                183                 :                : {
                                184                 :                :     /*
                                185                 :                :      * The enum values are chosen such that we have to decrease __pg_log_level
                                186                 :                :      * in order to become more verbose.
                                187                 :                :      */
                                188         [ +  - ]:             66 :     if (__pg_log_level > PG_LOG_NOTSET + 1)
                                189                 :             66 :         __pg_log_level--;
                                190                 :             66 : }
                                191                 :                : 
                                192                 :                : void
 1789                           193                 :           8208 : pg_logging_set_pre_callback(void (*cb) (void))
                                194                 :                : {
 1840 peter@eisentraut.org      195                 :           8208 :     log_pre_callback = cb;
                                196                 :           8208 : }
                                197                 :                : 
                                198                 :                : void
 1789 tgl@sss.pgh.pa.us         199                 :           8208 : pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno))
                                200                 :                : {
 1840 peter@eisentraut.org      201                 :           8208 :     log_locus_callback = cb;
                                202                 :           8208 : }
                                203                 :                : 
                                204                 :                : void
  737 tgl@sss.pgh.pa.us         205                 :         155593 : pg_log_generic(enum pg_log_level level, enum pg_log_part part,
                                206                 :                :                const char *pg_restrict fmt,...)
                                207                 :                : {
                                208                 :                :     va_list     ap;
                                209                 :                : 
 1840 peter@eisentraut.org      210                 :         155593 :     va_start(ap, fmt);
  737 tgl@sss.pgh.pa.us         211                 :         155593 :     pg_log_generic_v(level, part, fmt, ap);
 1840 peter@eisentraut.org      212                 :         155593 :     va_end(ap);
                                213                 :         155593 : }
                                214                 :                : 
                                215                 :                : void
  737 tgl@sss.pgh.pa.us         216                 :         155648 : pg_log_generic_v(enum pg_log_level level, enum pg_log_part part,
                                217                 :                :                  const char *pg_restrict fmt, va_list ap)
                                218                 :                : {
 1840 peter@eisentraut.org      219                 :         155648 :     int         save_errno = errno;
                                220                 :         155648 :     const char *filename = NULL;
                                221                 :         155648 :     uint64      lineno = 0;
                                222                 :                :     va_list     ap2;
                                223                 :                :     size_t      required_len;
                                224                 :                :     char       *buf;
                                225                 :                : 
                                226         [ -  + ]:         155648 :     Assert(progname);
                                227         [ -  + ]:         155648 :     Assert(level);
                                228         [ -  + ]:         155648 :     Assert(fmt);
                                229         [ -  + ]:         155648 :     Assert(fmt[strlen(fmt) - 1] != '\n');
                                230                 :                : 
                                231                 :                :     /* Do nothing if log level is too low. */
  733 tgl@sss.pgh.pa.us         232         [ +  + ]:         155648 :     if (level < __pg_log_level)
                                233                 :          36362 :         return;
                                234                 :                : 
                                235                 :                :     /*
                                236                 :                :      * Flush stdout before output to stderr, to ensure sync even when stdout
                                237                 :                :      * is buffered.
                                238                 :                :      */
 1840 peter@eisentraut.org      239                 :         119286 :     fflush(stdout);
                                240                 :                : 
                                241         [ +  + ]:         119286 :     if (log_pre_callback)
                                242                 :          96690 :         log_pre_callback();
                                243                 :                : 
                                244         [ +  + ]:         119286 :     if (log_locus_callback)
                                245                 :          96690 :         log_locus_callback(&filename, &lineno);
                                246                 :                : 
                                247                 :         119286 :     fmt = _(fmt);
                                248                 :                : 
  685                           249   [ +  +  -  + ]:         119286 :     if (!(log_flags & PG_LOG_FLAG_TERSE) || filename)
                                250                 :                :     {
 1840                           251         [ -  + ]:          89505 :         if (sgr_locus)
 1840 peter@eisentraut.org      252                 :UBC           0 :             fprintf(stderr, ANSI_ESCAPE_FMT, sgr_locus);
 1840 peter@eisentraut.org      253         [ +  - ]:CBC       89505 :         if (!(log_flags & PG_LOG_FLAG_TERSE))
                                254                 :          89505 :             fprintf(stderr, "%s:", progname);
                                255         [ +  + ]:          89505 :         if (filename)
                                256                 :                :         {
                                257                 :          66673 :             fprintf(stderr, "%s:", filename);
                                258         [ +  - ]:          66673 :             if (lineno > 0)
                                259                 :          66673 :                 fprintf(stderr, UINT64_FORMAT ":", lineno);
                                260                 :                :         }
                                261                 :          89505 :         fprintf(stderr, " ");
                                262         [ -  + ]:          89505 :         if (sgr_locus)
 1840 peter@eisentraut.org      263                 :UBC           0 :             fprintf(stderr, ANSI_ESCAPE_RESET);
                                264                 :                :     }
                                265                 :                : 
 1840 peter@eisentraut.org      266         [ +  + ]:CBC      119286 :     if (!(log_flags & PG_LOG_FLAG_TERSE))
                                267                 :                :     {
  737 tgl@sss.pgh.pa.us         268   [ +  +  +  - ]:          89505 :         switch (part)
                                269                 :                :         {
                                270      [ +  +  + ]:          89357 :             case PG_LOG_PRIMARY:
                                271                 :                :                 switch (level)
                                272                 :                :                 {
                                273                 :            888 :                     case PG_LOG_ERROR:
                                274         [ -  + ]:            888 :                         if (sgr_error)
  737 tgl@sss.pgh.pa.us         275                 :UBC           0 :                             fprintf(stderr, ANSI_ESCAPE_FMT, sgr_error);
  737 tgl@sss.pgh.pa.us         276                 :CBC         888 :                         fprintf(stderr, _("error: "));
                                277         [ -  + ]:            888 :                         if (sgr_error)
  737 tgl@sss.pgh.pa.us         278                 :UBC           0 :                             fprintf(stderr, ANSI_ESCAPE_RESET);
  737 tgl@sss.pgh.pa.us         279                 :CBC         888 :                         break;
                                280                 :             88 :                     case PG_LOG_WARNING:
                                281         [ -  + ]:             88 :                         if (sgr_warning)
  737 tgl@sss.pgh.pa.us         282                 :UBC           0 :                             fprintf(stderr, ANSI_ESCAPE_FMT, sgr_warning);
  737 tgl@sss.pgh.pa.us         283                 :CBC          88 :                         fprintf(stderr, _("warning: "));
                                284         [ -  + ]:             88 :                         if (sgr_warning)
  737 tgl@sss.pgh.pa.us         285                 :UBC           0 :                             fprintf(stderr, ANSI_ESCAPE_RESET);
  737 tgl@sss.pgh.pa.us         286                 :CBC          88 :                         break;
                                287                 :          88381 :                     default:
                                288                 :          88381 :                         break;
                                289                 :                :                 }
 1840 peter@eisentraut.org      290                 :          89357 :                 break;
  737 tgl@sss.pgh.pa.us         291                 :             15 :             case PG_LOG_DETAIL:
  734 peter@eisentraut.org      292         [ -  + ]:             15 :                 if (sgr_note)
  734 peter@eisentraut.org      293                 :UBC           0 :                     fprintf(stderr, ANSI_ESCAPE_FMT, sgr_note);
  737 tgl@sss.pgh.pa.us         294                 :CBC          15 :                 fprintf(stderr, _("detail: "));
  734 peter@eisentraut.org      295         [ -  + ]:             15 :                 if (sgr_note)
  734 peter@eisentraut.org      296                 :UBC           0 :                     fprintf(stderr, ANSI_ESCAPE_RESET);
 1840 peter@eisentraut.org      297                 :CBC          15 :                 break;
  737 tgl@sss.pgh.pa.us         298                 :            133 :             case PG_LOG_HINT:
  734 peter@eisentraut.org      299         [ -  + ]:            133 :                 if (sgr_note)
  734 peter@eisentraut.org      300                 :UBC           0 :                     fprintf(stderr, ANSI_ESCAPE_FMT, sgr_note);
  737 tgl@sss.pgh.pa.us         301                 :CBC         133 :                 fprintf(stderr, _("hint: "));
  734 peter@eisentraut.org      302         [ -  + ]:            133 :                 if (sgr_note)
  734 peter@eisentraut.org      303                 :UBC           0 :                     fprintf(stderr, ANSI_ESCAPE_RESET);
 1840 peter@eisentraut.org      304                 :CBC         133 :                 break;
                                305                 :                :         }
                                306                 :                :     }
                                307                 :                : 
                                308                 :         119286 :     errno = save_errno;
                                309                 :                : 
                                310                 :         119286 :     va_copy(ap2, ap);
                                311                 :         119286 :     required_len = vsnprintf(NULL, 0, fmt, ap2) + 1;
                                312                 :         119286 :     va_end(ap2);
                                313                 :                : 
                                314                 :         119286 :     buf = pg_malloc_extended(required_len, MCXT_ALLOC_NO_OOM);
                                315                 :                : 
 1744 tgl@sss.pgh.pa.us         316                 :         119286 :     errno = save_errno;         /* malloc might change errno */
                                317                 :                : 
 1840 peter@eisentraut.org      318         [ -  + ]:         119286 :     if (!buf)
                                319                 :                :     {
                                320                 :                :         /* memory trouble, just print what we can and get out of here */
 1840 peter@eisentraut.org      321                 :UBC           0 :         vfprintf(stderr, fmt, ap);
                                322                 :              0 :         return;
                                323                 :                :     }
                                324                 :                : 
 1840 peter@eisentraut.org      325                 :CBC      119286 :     vsnprintf(buf, required_len, fmt, ap);
                                326                 :                : 
                                327                 :                :     /* strip one newline, for PQerrorMessage() */
 1797 tgl@sss.pgh.pa.us         328   [ +  -  +  + ]:         119286 :     if (required_len >= 2 && buf[required_len - 2] == '\n')
 1840 peter@eisentraut.org      329                 :          96168 :         buf[required_len - 2] = '\0';
                                330                 :                : 
                                331                 :         119286 :     fprintf(stderr, "%s\n", buf);
                                332                 :                : 
                                333                 :         119286 :     free(buf);
                                334                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622