Added module that can write events to log files.

git-svn-id: http://yate.null.ro/svn/yate/trunk@5047 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2012-05-07 16:05:30 +00:00
parent 8dc6c1200c
commit 8672ff9cbd
4 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,21 @@
[general]
; This section controls the global behavior of the events log module
; logs_dir: string: Base directory for event log files, must be set to enable the module
; The last component of the path will be created if missing
; Example: logs_dir=/var/log/yate-events
;logs_dir=
; public_read: bool: Make the log files publically readable
; This setting does not apply to Windows
;public_read=false
[mappings]
; This section maps event sources to file names
; Each line holds a regexp and a filename that can include replacements
; First line that matches writes to file name at right of = and exits
; You must take care to create valid file names
; If this section is missing or empty a default line is added:
; ^[A-Za-z0-9_-]\+ = \0.log

View File

@ -78,6 +78,7 @@ PROGS := cdrbuild.yate cdrfile.yate regexroute.yate \
$(JUSTSIG) \
server/analogdetect.yate \
server/cache.yate \
server/eventlogs.yate \
client/jabberclient.yate \
callgen.yate analyzer.yate rmanager.yate msgsniff.yate

View File

@ -0,0 +1,166 @@
/**
* eventlogs.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* Write the events and alerts to text log files
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2012 Null Team
*
* 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 of the License, 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <yatengine.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
using namespace TelEngine;
namespace { // anonymous
class EventLogsHandler : public MessageHandler, public Mutex
{
public:
EventLogsHandler(const char *name)
: MessageHandler(name), Mutex(false,"EventLogs"),
m_mappings("")
{ }
virtual bool received(Message &msg);
void init(const NamedList* mappings);
private:
bool writeLog(const char* name, const String& line);
NamedList m_mappings;
};
class EventLogsPlugin : public Plugin
{
public:
EventLogsPlugin();
~EventLogsPlugin();
virtual void initialize();
private:
EventLogsHandler* m_handler;
};
#ifdef _WINDOWS
const char eoln[] = { '\r', '\n' };
#else
const char eoln[] = { '\n' };
#endif
static String s_baseDir;
static bool s_pubRead = false;
INIT_PLUGIN(EventLogsPlugin);
bool EventLogsHandler::writeLog(const char* name, const String& line)
{
File f;
if (!f.openPath(name,true,false,true,true,true,s_pubRead))
return false;
f.writeData(line.c_str(),line.length());
f.writeData(eoln,sizeof(eoln));
return true;
}
bool EventLogsHandler::received(Message &msg)
{
if (!msg.getBoolValue(YSTRING("eventwrite_eventlogs"),true))
return false;
const String& from = msg[YSTRING("from")];
if (from.null())
return false;
const String& text = msg[YSTRING("fulltext")];
if (text.null())
return false;
String file;
Lock lock(this);
if (s_baseDir.null())
return false;
unsigned int len = m_mappings.length();
for (unsigned int i = 0; i < len; i++) {
const NamedString* n = m_mappings.getParam(i);
if (!n)
continue;
Regexp r(n->name());
String tmp(from);
if (tmp.matches(r)) {
file = tmp.replaceMatches(*n);
if (file)
break;
}
}
if (file) {
if (!file.startsWith(Engine::pathSeparator()))
file = s_baseDir + file;
if (!writeLog(file,text))
Debug(__plugin.name(),DebugWarn,"Failed to log to file '%s'",file.c_str());
}
return false;
};
void EventLogsHandler::init(const NamedList* mappings)
{
m_mappings.clearParams();
if (mappings)
m_mappings.copyParams(*mappings);
if (m_mappings.count() == 0)
m_mappings.addParam("^[A-Za-z0-9_-]\\+","\\0.log");
}
EventLogsPlugin::EventLogsPlugin()
: Plugin("eventlogs",true),
m_handler(0)
{
Output("Loaded module Event Logs");
}
EventLogsPlugin::~EventLogsPlugin()
{
Output("Unloading module Event Logs");
}
void EventLogsPlugin::initialize()
{
Output("Initializing module Event Logs");
Configuration cfg(Engine::configFile("eventlogs"));
String base = cfg.getValue("general","logs_dir");
Engine::self()->runParams().replaceParams(base);
if (base) {
File::mkDir(base);
if (!base.endsWith(Engine::pathSeparator()))
base += Engine::pathSeparator();
}
Lock lock(m_handler);
s_baseDir = base;
s_pubRead = cfg.getBoolValue("general","public_read");
if (m_handler)
m_handler->init(cfg.getSection("mappings"));
else if (base) {
m_handler = new EventLogsHandler("module.update");
m_handler->init(cfg.getSection("mappings"));
Engine::install(m_handler);
}
}
}; // anonymous namespace
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -153,6 +153,7 @@ for small to large scale projects.
%{_libdir}/yate/server/monitoring.yate
%{_libdir}/yate/server/ysnmpagent.yate
%{_libdir}/yate/server/cache.yate
%{_libdir}/yate/server/eventlogs.yate
%{_libdir}/yate/client/osschan.yate
%{_libdir}/yate/client/jabberclient.yate
%{_libdir}/yate/jabber/jabberserver.yate
@ -207,6 +208,7 @@ for small to large scale projects.
%config(noreplace) %{_sysconfdir}/yate/monitoring.conf
%config(noreplace) %{_sysconfdir}/yate/ysnmpagent.conf
%config(noreplace) %{_sysconfdir}/yate/cache.conf
%config(noreplace) %{_sysconfdir}/yate/eventlogs.conf
%config(noreplace) %{_sysconfdir}/yate/users.conf
%config(noreplace) %{_sysconfdir}/yate/presence.conf
%config(noreplace) %{_sysconfdir}/yate/subscription.conf