Răsfoiți Sursa

log_custom: module that can replace logging to syslog with logging to a remote address via UDP

- reference of how to implement a custom logging mechanism
Daniel-Constantin Mierla 10 ani în urmă
părinte
comite
dbdaf6d1f9

+ 10 - 0
modules/log_custom/Makefile

@@ -0,0 +1,10 @@
+#
+# WARNING: do not run this directly, it should be run by the master Makefile
+
+include ../../Makefile.defs
+auto_gen=
+NAME=log_custom.so
+
+DEFS+=-DKAMAILIO_MOD_INTERFACE
+
+include ../../Makefile.modules

+ 111 - 0
modules/log_custom/README

@@ -0,0 +1,111 @@
+LOG_CUSTOM Module
+
+Daniel-Constantin Mierla
+
+   <[email protected]>
+
+Edited by
+
+Daniel-Constantin Mierla
+
+   <[email protected]>
+
+   Copyright © 2015 asipto.com
+     __________________________________________________________________
+
+   Table of Contents
+
+   1. Admin Guide
+
+        1. Overview
+        2. Dependencies
+
+              2.1. Kamailio Modules
+              2.2. External Libraries or Applications
+
+        3. Core Logging
+        4. Functions
+
+              4.1. log_udp(text)
+
+   List of Examples
+
+   1.1. log_udp usage
+   1.2. log_udp usage
+
+Chapter 1. Admin Guide
+
+   Table of Contents
+
+   1. Overview
+   2. Dependencies
+
+        2.1. Kamailio Modules
+        2.2. External Libraries or Applications
+
+   3. Core Logging
+   4. Functions
+
+        4.1. log_udp(text)
+
+1. Overview
+
+   This module provides logging to custom systems, replacing the default
+   core logging to syslog. At this moment it can send the logs to an IP
+   and port via UDP, once all modules have been initialized.
+
+2. Dependencies
+
+   2.1. Kamailio Modules
+   2.2. External Libraries or Applications
+
+2.1. Kamailio Modules
+
+   The following modules must be loaded before this module:
+     * none.
+
+2.2. External Libraries or Applications
+
+   The following libraries or applications must be installed before
+   running Kamailio with this module loaded:
+     * none
+
+3. Core Logging
+
+   This module can replace the syslog logging with sending the log
+   messages to a remote address and port via UDP. The logging to remote
+   target is started when all the modules are initialized, before that the
+   default syslog system is used.
+
+   It requires that core parameters log_engine_type to be set to 'udp' and
+   log_engine_data to be set to target 'address:port'. It is not enabled
+   if log_stderror=yes.
+
+   Example 1.1. log_udp usage
+...
+log_engine_type="udp"
+log_engine_data="127.0.0.1:9"
+...
+loadmodule "log_custom.so"
+...
+
+4. Functions
+
+   4.1. log_udp(text)
+
+4.1. log_udp(text)
+
+   Send the text to the address specified in core parameter
+   log_engine_data. It is provided as sample function mainly for testing,
+   because all logs messages printed by kamailio should be diverted as
+   described in the section 'Core Logging', so you can use xlog functions
+   in config file.
+
+   The parameter can contain variables.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.2. log_udp usage
+...
+   log_udp("R-URI is $ru\n");
+...

+ 4 - 0
modules/log_custom/doc/Makefile

@@ -0,0 +1,4 @@
+docs = log_custom.xml
+
+docbook_dir = ../../../docbook
+include $(docbook_dir)/Makefile.module

+ 37 - 0
modules/log_custom/doc/log_custom.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
+%docentities;
+
+]>
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+    <bookinfo>
+	<title>LOG_CUSTOM Module</title>
+	<productname class="trade">kamailio.org</productname>
+	<authorgroup>
+	    <author>
+		<firstname>Daniel-Constantin</firstname>
+		<surname>Mierla</surname>
+		<email>[email protected]</email>
+	    </author>
+	    <editor>
+		<firstname>Daniel-Constantin</firstname>
+		<surname>Mierla</surname>
+		<email>[email protected]</email>
+	    </editor>
+	</authorgroup>
+	<copyright>
+	    <year>2015</year>
+	    <holder>asipto.com</holder>
+	</copyright>
+    </bookinfo>
+    <toc></toc>
+    
+    <xi:include href="log_custom_admin.xml"/>
+    
+    
+</book>

+ 112 - 0
modules/log_custom/doc/log_custom_admin.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
+%docentities;
+
+]>
+<!-- Module User's Guide -->
+
+<chapter>
+	
+	<title>&adminguide;</title>
+	
+	<section>
+	<title>Overview</title>
+	<para>
+		This module provides logging to custom systems, replacing the
+		default core logging to syslog. At this moment it can send the
+		logs to an IP and port via UDP, once all modules have been
+		initialized.
+	</para>
+	</section>
+
+	<section>
+	<title>Dependencies</title>
+	<section>
+		<title>&kamailio; Modules</title>
+		<para>
+		The following modules must be loaded before this module:
+			<itemizedlist>
+			<listitem>
+			<para>
+				<emphasis>none</emphasis>.
+			</para>
+			</listitem>
+			</itemizedlist>
+		</para>
+	</section>
+	<section>
+		<title>External Libraries or Applications</title>
+		<para>
+		The following libraries or applications must be installed before running
+		&kamailio; with this module loaded:
+			<itemizedlist>
+			<listitem>
+			<para>
+				<emphasis>none</emphasis>
+			</para>
+			</listitem>
+			</itemizedlist>
+		</para>
+	</section>
+	</section>
+
+	<section>
+	<title>Core Logging</title>
+		<para>
+		This module can replace the syslog logging with sending the log messages
+		to a remote address and port via UDP. The logging to remote target is
+		started when all the modules are initialized, before that the default
+		syslog system is used.
+		</para>
+		<para>
+		It requires that core parameters log_engine_type to be set to 'udp' and
+		log_engine_data to be set to target 'address:port'.  It is not enabled
+		if log_stderror=yes.
+		</para>
+		<example>
+		<title><function>log_udp</function> usage</title>
+		<programlisting format="linespecific">
+...
+log_engine_type="udp"
+log_engine_data="127.0.0.1:9"
+...
+loadmodule "log_custom.so"
+...
+</programlisting>
+	    </example>
+	</section>
+
+	<section>
+	<title>Functions</title>
+	<section id="log_custom.f.log_udp">
+	    <title>
+		<function moreinfo="none">log_udp(text)</function>
+	    </title>
+		<para>
+		Send the text to the address specified in core parameter log_engine_data.
+		It is provided as sample function mainly for testing, because all logs
+		messages printed by kamailio should be diverted as described in the
+		section 'Core Logging', so you can use xlog functions in config file.
+		</para>
+		<para>
+		The parameter can contain variables.
+		</para>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title><function>log_udp</function> usage</title>
+		<programlisting format="linespecific">
+...
+   log_udp("R-URI is $ru\n");
+...
+</programlisting>
+	    </example>
+	</section>
+	</section>
+</chapter>
+

+ 196 - 0
modules/log_custom/log_custom_mod.c

@@ -0,0 +1,196 @@
+/**
+ * Copyright (C) 2015 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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 of the License, or
+ * (at your option) any later version
+ *
+ *
+ * This file 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "../../sr_module.h"
+#include "../../dprint.h"
+#include "../../mod_fix.h"
+#include "../../forward.h"
+#include "../../resolve.h"
+#include "../../udp_server.h"
+
+MODULE_VERSION
+
+static int _lc_log_udp = 0;
+static struct dest_info _lc_udp_dst = {0};
+
+static int  mod_init(void);
+static int  child_init(int);
+static void mod_destroy(void);
+
+static int w_log_udp(struct sip_msg* msg, char* txt, char* p2);
+
+void _lc_core_log_udp(int lpriority, const char *format, ...);
+
+static cmd_export_t cmds[]={
+	{"log_udp", (cmd_function)w_log_udp, 1, fixup_spve_null,
+		0, ANY_ROUTE},
+	{0, 0, 0, 0, 0, 0}
+};
+
+static param_export_t params[]={
+	{0, 0, 0}
+};
+
+struct module_exports exports = {
+	"log_custom",
+	DEFAULT_DLFLAGS, /* dlopen flags */
+	cmds,
+	params,
+	0,
+	0,              /* exported MI functions */
+	0,              /* exported pseudo-variables */
+	0,              /* extra processes */
+	mod_init,       /* module initialization function */
+	0,              /* response function */
+	mod_destroy,    /* destroy function */
+	child_init      /* per child init function */
+};
+
+
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
+{
+	str dest = {0};
+	int ret = 0;
+	struct sip_uri next_hop, *u;
+	char *p;
+
+	if(_km_log_engine_type==0 || _km_log_engine_data==0)
+		return 0;
+
+
+	if(strcasecmp(_km_log_engine_type, "udp")!=0)
+		return 0;
+
+	dest.s = _km_log_engine_data;
+	dest.len = strlen(dest.s);
+
+	init_dest_info(&_lc_udp_dst);
+
+	u = &next_hop;
+	u->port_no = 5060;
+	u->host = dest;
+	p = dest.s;
+	/* detect ipv6 */
+	p = memchr(p, ']', dest.len);
+	if (p) p++;
+	else p = dest.s;
+	p = memchr(p, ':', dest.len - (p - dest.s));
+	if (p) {
+		u->host.len = p - dest.s;
+		p++;
+		u->port_no = str2s(p, dest.len - (p - dest.s), NULL);
+	}
+
+	ret = sip_hostport2su(&_lc_udp_dst.to, &u->host, u->port_no,
+			&_lc_udp_dst.proto);
+	if(ret!=0) {
+		LM_ERR("failed to resolve [%.*s]\n", u->host.len,
+				ZSW(u->host.s));
+		return -1;;
+	}
+
+	return 0;
+}
+
+/**
+ * init module function
+ */
+static int mod_init(void)
+{
+	return 0;
+}
+
+/**
+ * @brief Initialize async module children
+ */
+static int child_init(int rank)
+{
+	if(rank!=PROC_INIT)
+		return 0;
+
+	_lc_udp_dst.proto = PROTO_UDP;
+	_lc_udp_dst.send_sock=get_send_socket(NULL, &_lc_udp_dst.to, PROTO_UDP);
+	if (_lc_udp_dst.send_sock==0) {
+		_lc_udp_dst.send_sock = get_out_socket(&_lc_udp_dst.to, PROTO_UDP);
+		if (_lc_udp_dst.send_sock==0) {
+			LM_ERR("failed to get send socket\n");
+			return -1;
+		}
+	}
+	km_log_func_set(&_lc_core_log_udp);
+	_lc_log_udp = 1;
+
+
+
+	return 0;
+}
+/**
+ * destroy module function
+ */
+static void mod_destroy(void)
+{
+}
+
+/**
+ *
+ */
+static int w_log_udp(struct sip_msg* msg, char* txt, char* p2)
+{
+	str stxt;
+	int ret;
+
+	if(_lc_log_udp==0)
+		return 1;
+
+	if(fixup_get_svalue(msg, (gparam_t*)txt, &stxt)!=0) {
+		LM_ERR("unable to get text parameter\n");
+		return -1;
+	}
+
+	ret=udp_send(&_lc_udp_dst, stxt.s, stxt.len);
+
+	if(ret==0) return 1;
+
+	return ret;
+}
+
+#define LC_LOG_MSG_MAX_SIZE	16384
+void _lc_core_log_udp(int lpriority, const char *format, ...)
+{
+	va_list arglist;
+	char obuf[LC_LOG_MSG_MAX_SIZE];
+	int n;
+
+	va_start(arglist, format);
+
+	n = 0;
+	n += snprintf(obuf+n, 1024-n, "(%d) ", my_pid());
+	n += vsnprintf(obuf+n, 1024-n, format, arglist);
+	va_end(arglist);
+	udp_send(&_lc_udp_dst, obuf, n);
+}