fb22df9f40a57c27dbbfc84da1474bbdef07589e
[demo.git] / vnfs / VES5.0 / evel / evel-library / code / evel_library / evel_syslog.c
1 /*************************************************************************//**
2  *
3  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
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  ****************************************************************************/
17 /**************************************************************************//**
18  * @file
19  * Implementation of EVEL functions relating to the Syslog.
20  *
21  ****************************************************************************/
22
23 #include <string.h>
24 #include <assert.h>
25 #include <stdlib.h>
26
27 #include "evel_throttle.h"
28
29 /**************************************************************************//**
30  * Create a new Syslog event.
31  *
32  * @note    The mandatory fields on the Syslog must be supplied to this factory
33  *          function and are immutable once set.  Optional fields have explicit
34  *          setter functions, but again values may only be set once so that the
35  *          Syslog has immutable properties.
36  * @param   event_source_type  The type of Syslog event source.
37  * @param   syslog_msg         The Syslog event message.
38  * @param   syslog_tag         The messgaeId identifying the type of message.
39  * @returns pointer to the newly manufactured ::EVENT_SYSLOG.  If the event is
40  *          not used (i.e. posted) it must be released using
41  *          ::evel_free_syslog.
42  * @retval  NULL  Failed to create the event.
43  *****************************************************************************/
44 EVENT_SYSLOG * evel_new_syslog(EVEL_SOURCE_TYPES event_source_type,
45                                const char * const syslog_msg,
46                                const char * const syslog_tag)
47 {
48   EVENT_SYSLOG * syslog = NULL;
49   EVEL_ENTER();
50
51   /***************************************************************************/
52   /* Check preconditions.                                                    */
53   /***************************************************************************/
54   assert(event_source_type < EVEL_MAX_SOURCE_TYPES);
55   assert(syslog_msg != NULL);
56   assert(syslog_tag != NULL);
57
58   /***************************************************************************/
59   /* Allocate the Syslog.                                                    */
60   /***************************************************************************/
61   syslog = malloc(sizeof(EVENT_SYSLOG));
62   if (syslog == NULL)
63   {
64     log_error_state("Out of memory");
65     goto exit_label;
66   }
67   memset(syslog, 0, sizeof(EVENT_SYSLOG));
68   EVEL_DEBUG("New Syslog is at %lp", syslog);
69
70   /***************************************************************************/
71   /* Initialize the header & the Syslog fields.  Optional string values are  */
72   /* uninitialized (NULL).                                                   */
73   /***************************************************************************/
74   evel_init_header(&syslog->header,"Syslog");
75   syslog->header.event_domain = EVEL_DOMAIN_SYSLOG;
76   syslog->major_version = EVEL_SYSLOG_MAJOR_VERSION;
77   syslog->minor_version = EVEL_SYSLOG_MINOR_VERSION;
78   syslog->event_source_type = event_source_type;
79   syslog->syslog_msg = strdup(syslog_msg);
80   syslog->syslog_tag = strdup(syslog_tag);
81   evel_init_option_int(&syslog->syslog_facility);
82   evel_init_option_int(&syslog->syslog_proc_id);
83   evel_init_option_int(&syslog->syslog_ver);
84   evel_init_option_string(&syslog->additional_filters);
85   evel_init_option_string(&syslog->event_source_host);
86   evel_init_option_string(&syslog->syslog_proc);
87   evel_init_option_string(&syslog->syslog_s_data);
88   evel_init_option_string(&syslog->syslog_sdid);
89   evel_init_option_string(&syslog->syslog_severity);
90
91 exit_label:
92   EVEL_EXIT();
93   return syslog;
94 }
95
96 /**************************************************************************//**
97  * Set the Event Type property of the Syslog.
98  *
99  * @note  The property is treated as immutable: it is only valid to call
100  *        the setter once.  However, we don't assert if the caller tries to
101  *        overwrite, just ignoring the update instead.
102  *
103  * @param syslog      Pointer to the syslog.
104  * @param type        The Event Type to be set. ASCIIZ string. The caller
105  *                    does not need to preserve the value once the function
106  *                    returns.
107  *****************************************************************************/
108 void evel_syslog_type_set(EVENT_SYSLOG * syslog,
109                           const char * const type)
110 {
111   EVEL_ENTER();
112
113   /***************************************************************************/
114   /* Check preconditions and call evel_header_type_set.                      */
115   /***************************************************************************/
116   assert(syslog != NULL);
117   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
118   evel_header_type_set(&syslog->header, type);
119
120   EVEL_EXIT();
121 }
122
123 /**************************************************************************//**
124  * Add an additional value name/value pair to the Syslog.
125  *
126  * The name and value are null delimited ASCII strings.  The library takes
127  * a copy so the caller does not have to preserve values after the function
128  * returns.
129  *
130  * @param syslog    Pointer to the syslog.
131  * @param name      ASCIIZ string with the attribute's name.  The caller
132  *                  does not need to preserve the value once the function
133  *                  returns.
134  * @param value     ASCIIZ string with the attribute's value.  The caller
135  *                  does not need to preserve the value once the function
136  *                  returns.
137  *****************************************************************************/
138 void evel_syslog_addl_filter_set(EVENT_SYSLOG * syslog,
139                                 char * filter)
140 {
141   EVEL_ENTER();
142
143   /***************************************************************************/
144   /* Check preconditions.                                                    */
145   /***************************************************************************/
146   assert(syslog != NULL);
147   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
148   assert(filter != NULL);
149
150   evel_set_option_string(&syslog->additional_filters,
151                          filter,
152                          "Syslog filter string");
153
154   EVEL_EXIT();
155 }
156
157 /**************************************************************************//**
158  * Set the Event Source Host property of the Syslog.
159  *
160  * @note  The property is treated as immutable: it is only valid to call
161  *        the setter once.  However, we don't assert if the caller tries to
162  *        overwrite, just ignoring the update instead.
163  *
164  * @param syslog     Pointer to the Syslog.
165  * @param host       The Event Source Host to be set. ASCIIZ string. The caller
166  *                   does not need to preserve the value once the function
167  *                   returns.
168  *****************************************************************************/
169 void evel_syslog_event_source_host_set(EVENT_SYSLOG * syslog,
170                                        const char * const host)
171 {
172   EVEL_ENTER();
173
174   /***************************************************************************/
175   /* Check preconditions.                                                    */
176   /***************************************************************************/
177   assert(syslog != NULL);
178   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
179   assert(host != NULL);
180
181   evel_set_option_string(&syslog->event_source_host,
182                          host,
183                          "Event Source Host");
184   EVEL_EXIT();
185 }
186
187 /**************************************************************************//**
188  * Set the Facility property of the Syslog.
189  *
190  * @note  The property is treated as immutable: it is only valid to call
191  *        the setter once.  However, we don't assert if the caller tries to
192  *        overwrite, just ignoring the update instead.
193  *
194  * @param syslog      Pointer to the Syslog.
195  * @param facility    The Syslog Facility to be set.  ASCIIZ string. The caller
196  *                    does not need to preserve the value once the function
197  *                    returns.
198  *****************************************************************************/
199 void evel_syslog_facility_set(EVENT_SYSLOG * syslog,
200                               EVEL_SYSLOG_FACILITIES facility)
201 {
202   EVEL_ENTER();
203
204   /***************************************************************************/
205   /* Check preconditions.                                                    */
206   /***************************************************************************/
207   assert(syslog != NULL);
208   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
209   assert(facility < EVEL_MAX_SYSLOG_FACILITIES);
210
211   evel_set_option_int(&syslog->syslog_facility,
212                       facility,
213                       "Facility");
214   EVEL_EXIT();
215 }
216
217 /**************************************************************************//**
218  * Set the Process property of the Syslog.
219  *
220  * @note  The property is treated as immutable: it is only valid to call
221  *        the setter once.  However, we don't assert if the caller tries to
222  *        overwrite, just ignoring the update instead.
223  *
224  * @param syslog     Pointer to the Syslog.
225  * @param proc       The Process to be set. ASCIIZ string. The caller does not
226  *                   need to preserve the value once the function returns.
227  *****************************************************************************/
228 void evel_syslog_proc_set(EVENT_SYSLOG * syslog, const char * const proc)
229 {
230   EVEL_ENTER();
231
232   /***************************************************************************/
233   /* Check preconditions.                                                    */
234   /***************************************************************************/
235   assert(syslog != NULL);
236   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
237   assert(proc != NULL);
238
239   evel_set_option_string(&syslog->syslog_proc, proc, "Process");
240   EVEL_EXIT();
241 }
242
243 /**************************************************************************//**
244  * Set the Process ID property of the Syslog.
245  *
246  * @note  The property is treated as immutable: it is only valid to call
247  *        the setter once.  However, we don't assert if the caller tries to
248  *        overwrite, just ignoring the update instead.
249  *
250  * @param syslog     Pointer to the Syslog.
251  * @param proc_id    The Process ID to be set. ASCIIZ string. The caller does
252  *                   not need to preserve the value once the function returns.
253  *****************************************************************************/
254 void evel_syslog_proc_id_set(EVENT_SYSLOG * syslog, int proc_id)
255 {
256   EVEL_ENTER();
257
258   /***************************************************************************/
259   /* Check preconditions.                                                    */
260   /***************************************************************************/
261   assert(syslog != NULL);
262   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
263   assert(proc_id > 0);
264
265   evel_set_option_int(&syslog->syslog_proc_id,
266                       proc_id,
267                       "Process ID");
268   EVEL_EXIT();
269 }
270
271 /**************************************************************************//**
272  * Set the Version property of the Syslog.
273  *
274  * @note  The property is treated as immutable: it is only valid to call
275  *        the setter once.  However, we don't assert if the caller tries to
276  *        overwrite, just ignoring the update instead.
277  *
278  * @param syslog     Pointer to the Syslog.
279  * @param version    The Version to be set. ASCIIZ string. The caller does not
280  *                   need to preserve the value once the function returns.
281  *****************************************************************************/
282 void evel_syslog_version_set(EVENT_SYSLOG * syslog, int version)
283 {
284   EVEL_ENTER();
285
286   /***************************************************************************/
287   /* Check preconditions.                                                    */
288   /***************************************************************************/
289   assert(syslog != NULL);
290   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
291   assert(version >= 0);
292
293   evel_set_option_int(&syslog->syslog_ver,
294                       version,
295                       "Version");
296   EVEL_EXIT();
297 }
298
299 /**************************************************************************//**
300  * Set the Structured Data property of the Syslog.
301  *
302  * @note  The property is treated as immutable: it is only valid to call
303  *        the setter once.  However, we don't assert if the caller tries to
304  *        overwrite, just ignoring the update instead.
305  *
306  * @param syslog     Pointer to the Syslog.
307  * @param s_data     The Structured Data to be set. ASCIIZ string. The caller
308  *                   does not need to preserve the value once the function
309  *                   returns.
310  *****************************************************************************/
311 void evel_syslog_s_data_set(EVENT_SYSLOG * syslog, const char * const s_data)
312 {
313   EVEL_ENTER();
314
315   /***************************************************************************/
316   /* Check preconditions.                                                    */
317   /***************************************************************************/
318   assert(syslog != NULL);
319   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
320   assert(s_data != NULL);
321
322   evel_set_option_string(&syslog->syslog_s_data,
323                          s_data,
324                          "Structured Data");
325   EVEL_EXIT();
326 }
327
328 /**************************************************************************//**
329  * Set the Structured SDID property of the Syslog.
330  *
331  * @note  The property is treated as immutable: it is only valid to call
332  *        the setter once.  However, we don't assert if the caller tries to
333  *        overwrite, just ignoring the update instead.
334  *
335  * @param syslog     Pointer to the Syslog.
336  * @param sdid     The Structured Data to be set. ASCIIZ string. name@number
337  *                 Caller does not need to preserve the value once the function
338  *                   returns.
339  *****************************************************************************/
340 void evel_syslog_sdid_set(EVENT_SYSLOG * syslog, const char * const sdid)
341 {
342   EVEL_ENTER();
343
344   /***************************************************************************/
345   /* Check preconditions.                                                    */
346   /***************************************************************************/
347   assert(syslog != NULL);
348   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
349   assert(sdid != NULL);
350
351   evel_set_option_string(&syslog->syslog_sdid,
352                          sdid,
353                          "SdId set");
354   EVEL_EXIT();
355 }
356
357 /**************************************************************************//**
358  * Set the Structured Severity property of the Syslog.
359  *
360  * @note  The property is treated as immutable: it is only valid to call
361  *        the setter once.  However, we don't assert if the caller tries to
362  *        overwrite, just ignoring the update instead.
363  *
364  * @param syslog     Pointer to the Syslog.
365  * @param sdid     The Structured Data to be set. ASCIIZ string. 
366  *                 Caller does not need to preserve the value once the function
367  *                   returns.
368  *****************************************************************************/
369 void evel_syslog_severity_set(EVENT_SYSLOG * syslog, const char * const severty)
370 {
371   EVEL_ENTER();
372
373   /***************************************************************************/
374   /* Check preconditions.                                                    */
375   /***************************************************************************/
376   assert(syslog != NULL);
377   assert(syslog->header.event_domain == EVEL_DOMAIN_SYSLOG);
378   assert(severty != NULL);
379
380   if( !strcmp(severty,"Alert") || !strcmp(severty,"Critical") || !strcmp(severty,"Debug") ||
381       !strcmp(severty,"Emergency") || !strcmp(severty,"Error") || !strcmp(severty,"Info") ||
382       !strcmp(severty,"Notice") || !strcmp(severty,"Warning") )
383   {
384      evel_set_option_string(&syslog->syslog_severity,
385                          severty,
386                          "Severity set");
387   }
388   EVEL_EXIT();
389 }
390
391 /**************************************************************************//**
392  * Encode the Syslog in JSON according to AT&T's schema for the event type.
393  *
394  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
395  * @param event         Pointer to the ::EVENT_HEADER to encode.
396  *****************************************************************************/
397 void evel_json_encode_syslog(EVEL_JSON_BUFFER * jbuf,
398                              EVENT_SYSLOG * event)
399 {
400   char * event_source_type;
401
402   EVEL_ENTER();
403
404   /***************************************************************************/
405   /* Check preconditions.                                                    */
406   /***************************************************************************/
407   assert(event != NULL);
408   assert(event->header.event_domain == EVEL_DOMAIN_SYSLOG);
409
410   event_source_type = evel_source_type(event->event_source_type);
411
412   evel_json_encode_header(jbuf, &event->header);
413   evel_json_open_named_object(jbuf, "syslogFields");
414
415   evel_enc_kv_opt_string(jbuf, "additionalFields", &event->additional_filters);
416   /***************************************************************************/
417   /* Mandatory fields                                                        */
418   /***************************************************************************/
419   evel_enc_kv_string(jbuf, "eventSourceType", event_source_type);
420   evel_enc_kv_string(jbuf, "syslogMsg", event->syslog_msg);
421   evel_enc_kv_string(jbuf, "syslogTag", event->syslog_tag);
422   evel_enc_version(
423     jbuf, "syslogFieldsVersion", event->major_version, event->minor_version);
424
425   /***************************************************************************/
426   /* Optional fields                                                         */
427   /***************************************************************************/
428   evel_enc_kv_opt_string(jbuf, "eventSourceHost", &event->event_source_host);
429   evel_enc_kv_opt_int(jbuf, "syslogFacility", &event->syslog_facility);
430   evel_enc_kv_opt_int(jbuf, "syslogPri", &event->syslog_priority);
431   evel_enc_kv_opt_string(jbuf, "syslogProc", &event->syslog_proc);
432   evel_enc_kv_opt_int(jbuf, "syslogProcId", &event->syslog_proc_id);
433   evel_enc_kv_opt_string(jbuf, "syslogSData", &event->syslog_s_data);
434   evel_enc_kv_opt_string(jbuf, "syslogSdId", &event->syslog_sdid);
435   evel_enc_kv_opt_string(jbuf, "syslogSev", &event->syslog_severity);
436   evel_enc_kv_opt_int(jbuf, "syslogVer", &event->syslog_ver);
437   evel_json_close_object(jbuf);
438
439   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_KERNEL == 0);
440   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_USER == 1);
441   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_MAIL == 2);
442   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_SYSTEM_DAEMON == 3);
443   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_SECURITY_AUTH == 4);
444   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_INTERNAL == 5);
445   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LINE_PRINTER == 6);
446   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_NETWORK_NEWS == 7);
447   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_UUCP == 8);
448   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_CLOCK_DAEMON == 9);
449   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_SECURITY_AUTH2 == 10);
450   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_FTP_DAEMON == 11);
451   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_NTP == 12);
452   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOG_AUDIT == 13);
453   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOG_ALERT == 14);
454   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_CLOCK_DAEMON2 == 15);
455   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL0 == 16);
456   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL1 == 17);
457   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL2 == 18);
458   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL3 == 19);
459   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL4 == 20);
460   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL5 == 21);
461   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL6 == 22);
462   EVEL_CT_ASSERT(EVEL_SYSLOG_FACILITY_LOCAL7 == 23);
463
464   EVEL_EXIT();
465 }
466
467 /**************************************************************************//**
468  * Free a Syslog.
469  *
470  * Free off the Syslog supplied.  Will free all the contained allocated memory.
471  *
472  * @note It does not free the Syslog itself, since that may be part of a
473  * larger structure.
474  *****************************************************************************/
475 void evel_free_syslog(EVENT_SYSLOG * event)
476 {
477
478   EVEL_ENTER();
479
480   /***************************************************************************/
481   /* Check preconditions.  As an internal API we don't allow freeing NULL    */
482   /* events as we do on the public API.                                      */
483   /***************************************************************************/
484   assert(event != NULL);
485   assert(event->header.event_domain == EVEL_DOMAIN_SYSLOG);
486
487   /***************************************************************************/
488   /* Free all internal strings then the header itself.                       */
489   /***************************************************************************/
490
491   evel_free_option_string(&event->additional_filters);
492   evel_free_option_string(&event->event_source_host);
493   free(event->syslog_msg);
494   evel_free_option_string(&event->syslog_proc);
495   evel_free_option_string(&event->syslog_s_data);
496   evel_free_option_string(&event->syslog_sdid);
497   evel_free_option_string(&event->syslog_severity);
498   free(event->syslog_tag);
499   evel_free_header(&event->header);
500
501   EVEL_EXIT();
502 }