From d0a103a343c22b2c557a490d559bc1ffaeadd265 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 14 Apr 2006 16:45:31 +0000 Subject: [PATCH] Addition of mod_syslog for *nix. Thanks to James Martelletti. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1158 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- AUTHORS | 1 + conf/freeswitch.conf | 18 +++ src/include/switch_utils.h | 2 + src/mod/loggers/mod_syslog/mod_syslog.c | 167 ++++++++++++++++++++++++ src/switch_utils.c | 49 +++++++ 5 files changed, 237 insertions(+) create mode 100644 src/mod/loggers/mod_syslog/mod_syslog.c diff --git a/AUTHORS b/AUTHORS index bcb6fc6787..28efc0884f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,6 +20,7 @@ that much better: Brian K. West - For countless hours of work on BSD and Mac support, finding countless bugs, and moral support. Michal "cypromis" Bielicki (michal.bielicki AT halo2.pl) - Solaris porting, and autotools enhancements. + James Martelletti - All around cool guy (mod_syslog) A big THANK YOU goes to: diff --git a/conf/freeswitch.conf b/conf/freeswitch.conf index cd3a828b89..94614bf964 100644 --- a/conf/freeswitch.conf +++ b/conf/freeswitch.conf @@ -18,6 +18,7 @@ ; Loggers (I'd load these first) load => mod_console +load => mod_syslog ; Event Handlers ;load => mod_event_multicast @@ -67,6 +68,23 @@ load => mod_softtimer ; ASR /TTS ;load => mod_cepstral +;---- SYSLOG +;-------------------------------------------------------------------------------- +; emerg - system is unusable +; alert - action must be taken immediately +; crit - critical conditions +; err - error conditions +; warning - warning conditions +; notice - normal, but significant, condition +; info - informational message +; debug - debug-level message +; +[+syslog.conf] +[settings] +ident => freeswitch +facility => user +format => ${time} - ${message} +level => debug,info,warning-alert ;---- IAX PROTOCOL diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index f1eb714076..fc2d54872c 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -174,6 +174,8 @@ SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms); */ SWITCH_DECLARE(char *) switch_cut_path(char *in); +SWITCH_DECLARE(char *) switch_string_replace(const char *string, const char *search, const char *replace); +SWITCH_DECLARE(switch_status) switch_string_match(const char *string, size_t string_len, const char *search, size_t search_len); #ifdef __cplusplus } diff --git a/src/mod/loggers/mod_syslog/mod_syslog.c b/src/mod/loggers/mod_syslog/mod_syslog.c new file mode 100644 index 0000000000..d3f14ce3c7 --- /dev/null +++ b/src/mod/loggers/mod_syslog/mod_syslog.c @@ -0,0 +1,167 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, James Martelletti + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * James Martelletti + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * James Martelletti + * + * + * mod_syslog.c -- System Logging + * + */ +#include +#include +#include + +#define DEFAULT_IDENT "freeswitch" +#define DEFAULT_FACILITY "user" +#define DEFAULT_LEVEL "warning" +#define DEFAULT_FORMAT "[message]" +#define MAX_LENGTH 1024 + +static const char modname[] = "mod_syslog"; +static switch_status load_config(void); + +static struct { + char *ident; + char *facility; + char *level; + char *format; +} globals; + +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ident, globals.ident) +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_level, globals.level) +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_format, globals.format) +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_facility, globals.facility) + +static switch_loadable_module_interface console_module_interface = { + /*.module_name */ modname, + /*.endpoint_interface */ NULL, + /*.timer_interface */ NULL, + /*.dialplan_interface */ NULL, + /*.codec_interface */ NULL, + /*.application_interface */ NULL, + /*.api_interface */ NULL, + /*.file_interface */ NULL, + /*.speech_interface */ NULL, + /*.directory_interface */ NULL +}; + +static switch_status mod_syslog_logger(const switch_log_node *node, switch_log_level level) +{ + char *message = NULL; + char line_no[sizeof(int)*8+1]; + char date[80] = ""; + switch_time_exp_t time; + switch_size_t retsize; + + message = (char *)malloc(strlen(globals.format)+2); + + switch_copy_string(message, globals.format, strlen(globals.format)+1); + + message = switch_string_replace(message, "${message}", node->content); + + if (switch_time_exp_lt(&time, node->timestamp) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + + switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &time); + message = switch_string_replace(message, "${time}", date); + + message = switch_string_replace(message, "${file}", node->file); + message = switch_string_replace(message, "${func}", node->func); + + snprintf(line_no, sizeof(line_no), "%d", node->line); + message = switch_string_replace(message, "${line}", line_no); + + if (!switch_strlen_zero(message)) { + syslog(LOG_ERR, "%s", message); + } + + free(message); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_module_interface **interface, char *filename) +{ + *interface = &console_module_interface; + + switch_log_bind_logger(mod_syslog_logger, SWITCH_LOG_DEBUG); + + load_config(); + + openlog(globals.ident, LOG_PID, LOG_USER); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MOD_DECLARE(switch_status) switch_module_unload(const switch_loadable_module_interface **interface) +{ + closelog(); + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status load_config(void) +{ + switch_config cfg; + char *var, *val; + char *cf = "syslog.conf"; + + if (!switch_config_open_file(&cfg, cf)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "open of %s failed\n", cf); + return SWITCH_STATUS_TERM; + } + + while (switch_config_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(cfg.category, "settings")) { + if (!strcmp(var, "ident")) { + set_global_ident(val); + } else if (!strcmp(var, "facility")) { + set_global_facility(val); + } else if (!strcmp(var, "format")) { + set_global_format(val); + } else if (!strcmp(var, "level")) { + set_global_level(val);; + } + } + } + + switch_config_close_file(&cfg); + + if (switch_strlen_zero(globals.ident)) { + set_global_ident(DEFAULT_IDENT); + } + if (switch_strlen_zero(globals.facility)) { + set_global_facility(DEFAULT_FACILITY); + } + if (switch_strlen_zero(globals.format)) { + set_global_format(DEFAULT_FORMAT); + } + if (switch_strlen_zero(globals.level)) { + set_global_level(DEFAULT_LEVEL); + } + + return SWITCH_STATUS_SUCCESS; +} diff --git a/src/switch_utils.c b/src/switch_utils.c index fc805effe3..26272401c1 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -30,6 +30,9 @@ * */ #include +#include +#include +#include SWITCH_DECLARE(char *) switch_priority_name(switch_priority_t priority) { @@ -141,6 +144,52 @@ SWITCH_DECLARE(switch_status) switch_socket_create_pollfd(switch_pollfd_t *poll, return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(switch_status) switch_string_match(const char *string, size_t string_len, const char *search, size_t search_len) +{ + size_t i; + + for (i = 0; (i < search_len) && (i < string_len); i++) { + if (string[i] != search[i]) { + return SWITCH_STATUS_FALSE; + } + } + + if (i == search_len) { + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(char *) switch_string_replace(const char *string, const char *search, const char *replace) +{ + size_t string_len = strlen(string); + size_t search_len = strlen(search); + size_t replace_len = strlen(replace); + size_t i, n; + size_t dest_len = 0; + char *dest; + + dest = (char *)malloc(sizeof(char)); + + for (i = 0; i < string_len; i++) { + if (switch_string_match(string + i, string_len - i, search, search_len) == SWITCH_STATUS_SUCCESS) { + for (n = 0; n < replace_len; n++) { + dest[dest_len] = replace[n]; + dest_len++; + dest = (char *)realloc(dest, sizeof(char)*(dest_len+1)); + } + i += search_len-1; + } else { + dest[dest_len] = string[i]; + dest_len++; + dest = (char *)realloc(dest, sizeof(char)*(dest_len+1)); + } + } + + dest[dest_len] = 0; + return dest; +} SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms) {