1 /*-
2  * Copyright 2020 Vsevolod Stakhov
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef RSPAMD_LOGGER_PRIVATE_H
17 #define RSPAMD_LOGGER_PRIVATE_H
18 
19 #include "logger.h"
20 
21 /* How much message should be repeated before it is count to be repeated one */
22 #define REPEATS_MIN 3
23 #define REPEATS_MAX 300
24 #define LOGBUF_LEN 8192
25 
26 struct rspamd_log_module {
27 	gchar *mname;
28 	guint id;
29 };
30 
31 struct rspamd_log_modules {
32 	guchar *bitset;
33 	guint bitset_len; /* Number of BITS used in bitset */
34 	guint bitset_allocated; /* Size of bitset allocated in BYTES */
35 	GHashTable *modules;
36 };
37 
38 struct rspamd_logger_error_elt {
39 	gint completed;
40 	GQuark ptype;
41 	pid_t pid;
42 	gdouble ts;
43 	gchar id[RSPAMD_LOG_ID_LEN + 1];
44 	gchar module[9];
45 	gchar message[];
46 };
47 
48 struct rspamd_logger_error_log {
49 	struct rspamd_logger_error_elt *elts;
50 	rspamd_mempool_t *pool;
51 	guint32 max_elts;
52 	guint32 elt_len;
53 	/* Avoid false cache sharing */
54 	guchar __padding[64 - sizeof(gpointer) * 2 - sizeof(guint64)];
55 	guint cur_row;
56 };
57 
58 /**
59  * Static structure that store logging parameters
60  * It is NOT shared between processes and is created by main process
61  */
62 struct rspamd_logger_s {
63 	struct rspamd_logger_funcs ops;
64 	gint log_level;
65 
66 	struct rspamd_logger_error_log *errlog;
67 	struct rspamd_cryptobox_pubkey *pk;
68 	struct rspamd_cryptobox_keypair *keypair;
69 
70 	guint flags;
71 	gboolean closed;
72 	gboolean enabled;
73 	gboolean is_debug;
74 	gboolean no_lock;
75 
76 	pid_t pid;
77 	const gchar *process_type;
78 	struct rspamd_radix_map_helper *debug_ip;
79 	rspamd_mempool_mutex_t *mtx;
80 	rspamd_mempool_t *pool;
81 	guint64 log_cnt[4];
82 };
83 
84 /*
85  * Common logging prototypes
86  */
87 
88 /*
89  * File logging
90  */
91 void * rspamd_log_file_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
92 							 uid_t uid, gid_t gid, GError **err);
93 void * rspamd_log_file_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
94 							   gpointer arg, uid_t uid, gid_t gid, GError **err);
95 void rspamd_log_file_dtor (rspamd_logger_t *logger, gpointer arg);
96 bool rspamd_log_file_log (const gchar *module, const gchar *id,
97 						  const gchar *function,
98 						  gint level_flags,
99 						  const gchar *message,
100 						  gsize mlen,
101 						  rspamd_logger_t *rspamd_log,
102 						  gpointer arg);
103 bool rspamd_log_file_on_fork (rspamd_logger_t *logger, struct rspamd_config *cfg,
104 							   gpointer arg, GError **err);
105 /**
106  * Escape log line by replacing unprintable characters to hex escapes like \xNN
107  * @param src
108  * @param srclen
109  * @param dst
110  * @param dstlen
111  * @return end of the escaped buffer
112  */
113 gchar* rspamd_log_line_hex_escape (const guchar *src, gsize srclen,
114 								  gchar *dst, gsize dstlen);
115 /**
116  * Returns number of characters to be escaped, e.g. a caller can allocate a new buffer
117  * the desired number of characters
118  * @param src
119  * @param srclen
120  * @return number of characters to be escaped
121  */
122 gsize rspamd_log_line_need_escape (const guchar *src, gsize srclen);
123 
124 static const struct rspamd_logger_funcs file_log_funcs = {
125 		.init = rspamd_log_file_init,
126 		.dtor = rspamd_log_file_dtor,
127 		.reload = rspamd_log_file_reload,
128 		.log = rspamd_log_file_log,
129 		.on_fork = rspamd_log_file_on_fork,
130 };
131 
132 /*
133  * Syslog logging
134  */
135 void * rspamd_log_syslog_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
136 							 uid_t uid, gid_t gid, GError **err);
137 void * rspamd_log_syslog_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
138 							   gpointer arg, uid_t uid, gid_t gid, GError **err);
139 void rspamd_log_syslog_dtor (rspamd_logger_t *logger, gpointer arg);
140 bool rspamd_log_syslog_log (const gchar *module, const gchar *id,
141 						  const gchar *function,
142 						  gint level_flags,
143 						  const gchar *message,
144 						  gsize mlen,
145 						  rspamd_logger_t *rspamd_log,
146 						  gpointer arg);
147 
148 static const struct rspamd_logger_funcs syslog_log_funcs = {
149 		.init = rspamd_log_syslog_init,
150 		.dtor = rspamd_log_syslog_dtor,
151 		.reload = rspamd_log_syslog_reload,
152 		.log = rspamd_log_syslog_log,
153 		.on_fork = NULL,
154 };
155 
156 /*
157  * Console logging
158  */
159 void * rspamd_log_console_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
160 							   uid_t uid, gid_t gid, GError **err);
161 void * rspamd_log_console_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
162 								 gpointer arg, uid_t uid, gid_t gid, GError **err);
163 void rspamd_log_console_dtor (rspamd_logger_t *logger, gpointer arg);
164 bool rspamd_log_console_log (const gchar *module, const gchar *id,
165 							const gchar *function,
166 							gint level_flags,
167 							const gchar *message,
168 							gsize mlen,
169 							rspamd_logger_t *rspamd_log,
170 							gpointer arg);
171 
172 static const struct rspamd_logger_funcs console_log_funcs = {
173 		.init = rspamd_log_console_init,
174 		.dtor = rspamd_log_console_dtor,
175 		.reload = rspamd_log_console_reload,
176 		.log = rspamd_log_console_log,
177 		.on_fork = NULL,
178 };
179 
180 #endif
181