diff options
author | Adam <Adam@anope.org> | 2013-08-07 16:44:35 +0000 |
---|---|---|
committer | Adam <Adam@anope.org> | 2013-08-07 16:44:35 +0000 |
commit | 4865a8cfff2fb2ab3acba89c5aabbb5f0db80743 (patch) | |
tree | 260869ecc5e32cb54201d01c13ad33bc765a750a | |
parent | 1efd289488ca16c895f833cded995d34b95daae1 (diff) |
Add m_sql_log
-rw-r--r-- | data/modules.example.conf | 20 | ||||
-rw-r--r-- | include/modules.h | 8 | ||||
-rw-r--r-- | modules/m_sql_log.cpp | 108 | ||||
-rw-r--r-- | src/logger.cpp | 6 |
4 files changed, 140 insertions, 2 deletions
diff --git a/data/modules.example.conf b/data/modules.example.conf index 28bef2850..aaf7048b2 100644 --- a/data/modules.example.conf +++ b/data/modules.example.conf @@ -458,6 +458,26 @@ module { name = "help" } } /* + * m_sql_log + * + * This module adds an additional target option to log{} blocks + * that allows logging Service's logs to SQL. To log to SQL, add + * the SQL service name to log:targets prefixed by sql_log:. For + * example: + * + * log + * { + * targets = "services.log sql_log:mysql/main" + * ... + * } + * + * By default this module logs to the table `logs`, and will create + * it if it doesn't exist. This module does not create any indexes (keys) + * on the table and it is recommended you add them yourself as necessary. + */ +#module { name = "m_sql_log" } + +/* * m_sql_oper * * This module allows granting users services operator privileges and possibly IRC Operator diff --git a/include/modules.h b/include/modules.h index b217b1b0e..14661d1c7 100644 --- a/include/modules.h +++ b/include/modules.h @@ -994,6 +994,14 @@ class CoreExport Module : public Extensible */ virtual void OnLog(Log *l) { throw NotImplementedException(); } + /** Called when a log message is actually logged to a given log info + * The message has already passed validation checks by the LogInfo + * @param li The loginfo whee the message is being logged + * @param l The log message + * @param msg The final formatted message, derived from 'l' + */ + virtual void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) { throw NotImplementedException(); } + /** Called when a DNS request (question) is recieved. * @param req The dns request * @param reply The reply that will be sent diff --git a/modules/m_sql_log.cpp b/modules/m_sql_log.cpp new file mode 100644 index 000000000..4bc02d31a --- /dev/null +++ b/modules/m_sql_log.cpp @@ -0,0 +1,108 @@ +/* + * + * (C) 2003-2013 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + */ + +#include "module.h" +#include "modules/sql.h" + +class SQLLog : public Module +{ + std::set<Anope::string> inited; + Anope::string table; + + public: + SQLLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) + { + } + + void OnReload(Configuration::Conf *conf) anope_override + { + Configuration::Block *config = conf->GetModule(this); + this->table = config->Get<const Anope::string>("table", "logs"); + } + + void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) anope_override + { + Anope::string ref_name; + ServiceReference<SQL::Provider> SQL; + + for (unsigned i = 0; i < li->targets.size(); ++i) + { + const Anope::string &target = li->targets[i]; + size_t sz = target.find("sql_log:"); + if (!sz) + { + ref_name = target.substr(8); + SQL = ServiceReference<SQL::Provider>("SQL::Provider", ref_name); + break; + } + } + + if (!SQL) + return; + + if (!inited.count(ref_name)) + { + inited.insert(ref_name); + + SQL::Query create("CREATE TABLE IF NOT EXISTS `" + table + "` (" + "`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP," + "`type` varchar(64) NOT NULL," + "`user` varchar(64) NOT NULL," + "`acc` varchar(64) NOT NULL," + "`command` varchar(64) NOT NULL," + "`channel` varchar(64) NOT NULL," + "`msg` text NOT NULL" + ")"); + + SQL->Run(NULL, create); + } + + SQL::Query insert("INSERT INTO `" + table + "` (`type`,`user`,`acc`,`command`,`channel`,`msg`)" + "VALUES (@type@, @user@, @acc@, @command@, @channel@, @msg@)"); + + switch (l->type) + { + case LOG_ADMIN: + insert.SetValue("type", "ADMIN"); + break; + case LOG_OVERRIDE: + insert.SetValue("type", "OVERRIDE"); + break; + case LOG_COMMAND: + insert.SetValue("type", "COMMAND"); + break; + case LOG_SERVER: + insert.SetValue("type", "SERVER"); + break; + case LOG_CHANNEL: + insert.SetValue("type", "CHANNEL"); + break; + case LOG_USER: + insert.SetValue("type", "USER"); + break; + case LOG_MODULE: + insert.SetValue("type", "MODULE"); + break; + case LOG_NORMAL: + insert.SetValue("type", "NORMAL"); + default: + return; + } + + insert.SetValue("user", l->u ? l->u->nick : ""); + insert.SetValue("acc", l->nc ? l->nc->display : ""); + insert.SetValue("command", l->c ? l->c->name : ""); + insert.SetValue("channel", l->ci ? l->ci->name : ""); + insert.SetValue("msg", msg); + + SQL->Run(NULL, insert); + } +}; + +MODULE_INIT(SQLLog) diff --git a/src/logger.cpp b/src/logger.cpp index dca46f6d8..e094f8da5 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -308,7 +308,7 @@ void LogInfo::OpenLogFiles() { const Anope::string &target = this->targets[i]; - if (target.empty() || target[0] == '#' || target == "globops") + if (target.empty() || target[0] == '#' || target == "globops" || target.find(":") != Anope::string::npos) continue; LogFile *lf = new LogFile(CreateLogName(target)); @@ -350,6 +350,8 @@ void LogInfo::ProcessMessage(const Log *l) const Anope::string &buffer = l->BuildPrefix() + l->buf.str(); + FOREACH_MOD(OnLogMessage, (this, l, buffer)); + for (unsigned i = 0; i < this->targets.size(); ++i) { const Anope::string &target = this->targets[i]; @@ -391,7 +393,7 @@ void LogInfo::ProcessMessage(const Log *l) { const Anope::string &target = this->targets[i]; - if (target.empty() || target[0] == '#' || target == "globops") + if (target.empty() || target[0] == '#' || target == "globops" || target.find(":") != Anope::string::npos) continue; Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->log_age); |