summaryrefslogtreecommitdiff
path: root/src/libply/ply-logger.h
blob: 8d8ee87194445fbe8a9aa9fe1c8c70b759b5ffdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* ply-logger.h - logging and tracing facilities
 *
 * Copyright (C) 2007 Ray Strode <rstrode@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */
#ifndef PLY_LOGGER_H
#define PLY_LOGGER_H

#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

typedef struct _ply_logger ply_logger_t;

typedef enum
{
        PLY_LOGGER_FLUSH_POLICY_WHEN_ASKED = 0,
        PLY_LOGGER_FLUSH_POLICY_EVERY_TIME
} ply_logger_flush_policy_t;

typedef void (*ply_logger_filter_handler_t) (void         *user_data,
                                             const void   *in_bytes,
                                             size_t        in_size,
                                             void        **out_bytes,
                                             size_t       *out_size,
                                             ply_logger_t *logger);

#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_logger_t *ply_logger_new (void);
void ply_logger_free (ply_logger_t *logger);
bool ply_logger_open_file (ply_logger_t *logger,
                           const char   *filename);
void ply_logger_close_file (ply_logger_t *logger);
void ply_logger_set_output_fd (ply_logger_t *logger,
                               int           fd);
int ply_logger_get_output_fd (ply_logger_t *logger);
bool ply_logger_flush (ply_logger_t *logger);
void ply_logger_set_flush_policy (ply_logger_t             *logger,
                                  ply_logger_flush_policy_t policy);
ply_logger_flush_policy_t ply_logger_get_flush_policy (ply_logger_t *logger);
void ply_logger_toggle_logging (ply_logger_t *logger);
bool ply_logger_is_logging (ply_logger_t *logger);
void ply_logger_inject_bytes (ply_logger_t *logger,
                              const void   *bytes,
                              size_t        number_of_bytes);
void ply_logger_add_filter (ply_logger_t               *logger,
                            ply_logger_filter_handler_t filter_handler,
                            void                       *user_data);
#define ply_logger_inject(logger, format, args ...)                             \
        ply_logger_inject_with_non_literal_format_string (logger,              \
                                                          format "", ## args)
__attribute__((__format__ (__printf__, 2, 3)))
void ply_logger_inject_with_non_literal_format_string (ply_logger_t *logger,
                                                       const char   *format,
                                                       ...);

ply_logger_t *ply_logger_get_default (void);
ply_logger_t *ply_logger_get_error_default (void);

/* tracing is a debugging facility that incurs a hefty performance hit on the
 * program, so we conditionally compile support for it
 */
#ifdef PLY_ENABLE_TRACING
void ply_logger_toggle_tracing (ply_logger_t *logger);
bool ply_logger_is_tracing_enabled (ply_logger_t *logger);
bool ply_logger_is_tracing_to_terminal (ply_logger_t *logger);

#define ply_logger_trace(logger, format, args ...)                              \
        do                                                                             \
        {                                                                            \
                int _old_errno;                                                            \
                _old_errno = errno;                                                        \
                if (ply_logger_is_tracing_enabled (logger))                                \
                {                                                                        \
                        struct timespec timespec = { 0, 0 };                                   \
                        char buf[128];                                                         \
                        clock_gettime (CLOCK_MONOTONIC, &timespec);                            \
                        ply_logger_flush (logger);                                             \
                        snprintf (buf, sizeof(buf),                                            \
                                  "%02d:%02d:%02d.%03d %s:%d:%s",                              \
                                  (int)(timespec.tv_sec / 3600),                               \
                                  (int)((timespec.tv_sec / 60) % 60),                          \
                                  (int)(timespec.tv_sec % 60),                                 \
                                  (int)(timespec.tv_nsec / 1000000),                           \
                                  __FILE__, __LINE__, __func__);                               \
                        errno = _old_errno;                                                    \
                        ply_logger_inject (logger,                                             \
                                           "%-75.75s: " format "\n",                           \
                                           buf, ## args);                                      \
                        ply_logger_flush (logger);                                             \
                        errno = _old_errno;                                                    \
                }                                                                        \
        }                                                                            \
        while (0)
#else
#define ply_logger_trace(logger, format, args ...)
#define ply_logger_toggle_tracing(logger)
#define ply_logger_is_tracing_enabled(logger) (false)
#define ply_logger_is_tracing_to_terminal(logger) (false)
#endif /* PLY_ENABLE_TRACING */

/* convenience macros
 */
#define ply_open_log_file(filename)                                            \
        ply_logger_open_file (ply_logger_get_default (), filename)
#define ply_close_log_file()                                                   \
        ply_logger_close_file (ply_logger_get_default ())
#define ply_flush_log()                                                        \
        ply_logger_flush (ply_logger_get_default ())
#define ply_free_log()                                                         \
        ply_logger_free (ply_logger_get_default ())
#define ply_log(format, args ...)                                               \
        ply_logger_inject (ply_logger_get_default (), format "\n", ## args)
#define ply_log_without_new_line(format, args ...)                              \
        ply_logger_inject (ply_logger_get_default (), format, ## args)
#define ply_error(format, args ...)                                             \
        ply_logger_inject (ply_logger_get_error_default (), format "\n", ## args)
#define ply_error_without_new_line(format, args ...)                            \
        ply_logger_inject (ply_logger_get_error_default (), format, ## args)
#define ply_free_error_log()                                                   \
        ply_logger_free (ply_logger_get_error_default ())

#define ply_toggle_tracing()                                                   \
        ply_logger_toggle_tracing (ply_logger_get_error_default ())
#define ply_is_tracing()                                                       \
        ply_logger_is_tracing_enabled (ply_logger_get_error_default ())
#define ply_is_tracing_to_terminal()                                            \
        ply_logger_is_tracing_to_terminal (ply_logger_get_error_default ())
#define ply_trace(format, args ...)                                             \
        ply_logger_trace (ply_logger_get_error_default (), format, ## args)

#endif

#endif /* PLY_LOGGER_H */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */