From e10903cdee65121d198c749461e1c32b25beb920 Mon Sep 17 00:00:00 2001 From: Ahmed Al-Issaei Date: Sun, 3 May 2009 00:20:01 +0400 Subject: [PATCH] version 0.8.6 --- Appenders_API.txt | 52 +++++++++++++++++++++++++++++++++++++++++ CHANGELOG.txt | 11 +++++++++ ebin/log4erl.app | 2 +- include/log4erl.hrl | 2 +- priv/log4erl.conf | 13 +++++++++++ src/file_appender.erl | 2 +- src/log4erl.erl | 14 +++++++++++ src/log4erl_conf.erl | 1 + src/log4erl_lex.erl | 4 ++-- src/log_manager.erl | 2 +- src/smtp_appender.erl | 2 +- src/syslog_appender.erl | 14 ++++++++++- 12 files changed, 111 insertions(+), 8 deletions(-) diff --git a/Appenders_API.txt b/Appenders_API.txt index c82f907..a0c1bc8 100644 --- a/Appenders_API.txt +++ b/Appenders_API.txt @@ -126,3 +126,55 @@ Default port is 514. Default Format is the same as default format of file_appender +**> log4erl:add_file_appender(Logger, Appender, SpecFile) -> ok + Logger :: atom() + Appender :: atom() + + This will create a new appender and associate spec in Spec or in SpecFile to it. Spec and + content of SpecFile are the same as in add_file_appender/2 + + Example: + log4erl:add_file_appender(chat_log, file_logger, "../priv/chat_logs.conf"). + This will add another logger with the name "chat_log" and use configuration in + the file "../priv/chat_logs.conf" for it. To write to this log, you need to specify + the name of the logger. + +**> log4erl:add_xml_appender(Appender, Spec) -> ok + log4erl:add_xml_appender(Logger, Appender, Spec) -> ok + Logger :: atom() + Appender :: atom() + Spec :: tuple() + + @since version 0.8.6 + + This will create a new XML Appender with configuration specified in Spec where Spec is + {Dir, Fname, {Type, Max}, Rot, Suf, Level} | + {Dir, Fname, {Type, Max}, Rot, Suf, Level, XmlSpecs} + + All tuple elements are the same as in file_appender except for XmlSpecs. XmlSpecs is as follows + + XmlSpecs :: [XmlSpec] + XmlSpec :: {Name, Format, Type} + Name :: atom() | string() + Format :: string() + Type :: att | elem + + Each XmlSpec item represent an attribute or element in xml record for a log. For example: + {level, "%L", att} means that this record is going to have an attribute named 'level' with + value "%L", which is the level of the message. Therefore, the XmlSpec mentioned in the example + will result in a record like + .. + However, XmlSpec {level, "%L", elem} will result in the the following: + ...warn... + + All attributes and elements are pre-proccessed to escape XML (i.e. '<' replaced by '<') + + You cannot provide XmlSpecs in file-based configuration yet and default XmlSpecs will be used. + If you needed to change XmlSpecs, you'll have to add_xml_appender/2,3 manually. + + The default XmlSpecs if not provided is: + [{level, "%L", att}, + {date, "%j", att}, + {time, "%T", att}, + {message, "%l", elem}] + diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 190b362..540c792 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,14 @@ +log4erl 0.8.6: +============== +* Added xml_appender for outputing logs to xml files +* Changed default behaviour to use sync logging (helps to eleminate + crash due to many processes due to high load +* file_appender renames files when rotating instead of copying +* syslog_appender add missing facilities +* Updated leex to fix a critical bug +* Added error_logger_log4erl_h.erl which is a handler for error_logger + Makes it possible to forward error_logger logs to log4erl. + log4erl 0.8.5: ============== * Added new file configuration (log4erl:conf(File)). diff --git a/ebin/log4erl.app b/ebin/log4erl.app index ccb4323..592d6c5 100644 --- a/ebin/log4erl.app +++ b/ebin/log4erl.app @@ -2,7 +2,7 @@ %% application. {application, log4erl, [{description, "Logger for erlang in the spirit of Log4J"}, - {vsn, "0.8.5"}, + {vsn, "0.8.6"}, {modules, [log4erl]}, {registered,[log4erl]}, {applications, [kernel,stdlib]}, diff --git a/include/log4erl.hrl b/include/log4erl.hrl index e717cb5..b7f425d 100644 --- a/include/log4erl.hrl +++ b/include/log4erl.hrl @@ -12,7 +12,7 @@ -define(FILE_OPTIONS,[write, raw, binary, append]). -define(FILE_OPTIONS_ROTATE,[write, raw, binary]). -%-define(DEBUG, true). +%%-define(DEBUG, true). -ifdef(DEBUG). -define(LOG(X), io:format("~p: " ++ X,[?MODULE])). diff --git a/priv/log4erl.conf b/priv/log4erl.conf index d31a561..bc7ab63 100644 --- a/priv/log4erl.conf +++ b/priv/log4erl.conf @@ -18,6 +18,19 @@ logger{ } } +%% XML appender +logger xmllogs{ + xml_appender xml{ + level = all, + dir = "logs", + file = "xml_app", + type = size, + max = 10000, + suffix = xml, + rotation = 5 + } +} + %% email logger logger email_logger{ smtp_appender app3{ diff --git a/src/file_appender.erl b/src/file_appender.erl index dde383c..24ee43e 100644 --- a/src/file_appender.erl +++ b/src/file_appender.erl @@ -140,7 +140,7 @@ rotate(#file_appender{fd = Fd, dir=Dir, file_name=Fn, counter=Cntr, rotation=Ro Dir ++ "/" ++ Fn ++ "_" ++ integer_to_list(C) ++ "." ++ Suf end, ?LOG2("Renaming file from ~p to ~p~n",[Src, Fname]), - file:copy(Src, Fname), + file:rename(Src, Fname), {ok ,Fd2} = file:open(Src, ?FILE_OPTIONS_ROTATE), State2 = #file_appender{dir = Dir, file_name = Fn, fd = Fd2, counter=C, log_type = Ltype, rotation = Rot, suffix=Suf, level=Level, format=Format}, {ok, State2}. diff --git a/src/log4erl.erl b/src/log4erl.erl index 872c672..40d78ae 100644 --- a/src/log4erl.erl +++ b/src/log4erl.erl @@ -19,9 +19,11 @@ -export([add_console_appender/2, add_console_appender/3]). -export([add_smtp_appender/2, add_smtp_appender/3]). -export([add_syslog_appender/2, add_syslog_appender/3]). +-export([add_xml_appender/2, add_xml_appender/3]). -export([add_dummy_appender/2, add_dummy_appender/3]). -export([get_appenders/0, get_appenders/1]). -export([change_format/2, change_format/3]). +-export([error_logger_handler/0, error_logger_handler/1]). -export([log/2, log/3, log/4]). @@ -77,6 +79,12 @@ add_syslog_appender(Name, Conf) -> add_syslog_appender(Logger, Name, Conf) -> add_appender(Logger, {syslog_appender, Name}, Conf). +add_xml_appender(Name, Conf) -> + add_appender({xml_appender, Name}, Conf). + +add_xml_appender(Logger, Name, Conf) -> + add_appender(Logger, {xml_appender, Name}, Conf). + add_dummy_appender(AName, Conf) -> add_appender({dummy_appender, AName}, Conf). @@ -103,6 +111,12 @@ change_level(Appender, Level) -> change_level(Logger, Appender, Level) -> try_msg({change_level, Logger, Appender, Level}). +error_logger_handler() -> + error_logger_log4erl_h:add_handler(). + +error_logger_handler(Args) -> + error_logger_log4erl_h:add_handler(Args). + %% For default logger change_log_level(Level) -> try_msg({change_log_level, Level}). diff --git a/src/log4erl_conf.erl b/src/log4erl_conf.erl index 4baca4b..2680a14 100644 --- a/src/log4erl_conf.erl +++ b/src/log4erl_conf.erl @@ -24,6 +24,7 @@ parse(Tokens) -> end. conf(File) -> + application:start(log4erl), Tree = parse(leex(File)), traverse(Tree). diff --git a/src/log4erl_lex.erl b/src/log4erl_lex.erl index 5952785..be0bb41 100644 --- a/src/log4erl_lex.erl +++ b/src/log4erl_lex.erl @@ -90,12 +90,12 @@ token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); %% Accepting transition state, can take more chars. {A1,Alen1,[],L1,S1} -> %Need more chars to check - {more,{token,S1,Tcs,L1,Alen1,Tline,A1,Alen1}}; + {more,{token,S1,L1,Tcs,Alen1,Tline,A1,Alen1}}; {A1,Alen1,Ics1,L1,_S1} -> %Take what we got token_cont(Ics1, L1, yyaction(A1, Alen1, Tcs, Tline)); %% After a non-accepting state, maybe reach accept state later. {A1,Alen1,Tlen1,[],L1,S1} -> %Need more chars to check - {more,{token,S1,Tcs,L1,Tlen1,Tline,A1,Alen1}}; + {more,{token,S1,L1,Tcs,Tlen1,Tline,A1,Alen1}}; {reject,_Alen1,Tlen1,eof,L1,_S1} -> %No token match %% Check for partial token which is error. Ret = if Tlen1 > 0 -> {error,{Tline,?MODULE, diff --git a/src/log_manager.erl b/src/log_manager.erl index 05bc810..a01e9a3 100644 --- a/src/log_manager.erl +++ b/src/log_manager.erl @@ -77,7 +77,7 @@ log(Logger, Level, Log, Data) -> notify_logger(Logger, Msg) -> try - gen_event:notify(Logger, Msg) + gen_event:sync_notify(Logger, Msg) catch exit:noproc -> {error, no_such_logger} diff --git a/src/smtp_appender.erl b/src/smtp_appender.erl index 2e86a4c..edd970a 100644 --- a/src/smtp_appender.erl +++ b/src/smtp_appender.erl @@ -165,7 +165,7 @@ get_msg_opts(E) -> check_opts(Opts) -> case Opts of {error, E} -> - ?LOG2("error in getting opts with param ~p~n",[Server]), + ?LOG2("error in getting opts with param ~p~n",[Opts]), throw({smtp_appender_opts, E}); R -> R diff --git a/src/syslog_appender.erl b/src/syslog_appender.erl index c8c22f7..e555468 100644 --- a/src/syslog_appender.erl +++ b/src/syslog_appender.erl @@ -135,7 +135,19 @@ facility(news) -> (7 bsl 3); % network news subsystem facility(uucp) -> (8 bsl 3); % UUCP subsystem facility(cron) -> (9 bsl 3); % clock daemon facility(authpriv) -> (10 bsl 3); % security/authorization messages (private) -facility(ftp) -> (11 bsl 3); % ftp daemon +facility(ftp) -> (11 bsl 3); % ftp daemon +facility(ntp) -> (12 bsl 3); % ntp daemon +facility(audit) -> (13 bsl 3); % log audit +facility(alert) -> (14 bsl 3); % log alert +facility(clock) -> (15 bsl 3); % clock daemon +facility(local0) -> (16 bsl 3); % local use 0 +facility(local1) -> (17 bsl 3); % local use 1 +facility(local2) -> (18 bsl 3); % local use 2 +facility(local3) -> (19 bsl 3); % local use 3 +facility(local4) -> (20 bsl 3); % local use 4 +facility(local5) -> (21 bsl 3); % local use 5 +facility(local6) -> (22 bsl 3); % local use 6 +facility(local7) -> (23 bsl 3); % local use 7 facility(_) -> facility(user). % anything else is user %% priorities/facilities are encoded into a single 32-bit