Repository: couchdb-couch-log Updated Branches: refs/heads/master cc5540419 -> da0e48964
Add a syslog writer COUCHDB-3067 Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-log/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-log/commit/c572aae6 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-log/tree/c572aae6 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-log/diff/c572aae6 Branch: refs/heads/master Commit: c572aae63262dd0454cb549a215aa26bb7d2339e Parents: b6b766d Author: Paul J. Davis <[email protected]> Authored: Wed Jul 20 12:01:54 2016 -0500 Committer: Paul J. Davis <[email protected]> Committed: Thu Jul 21 18:10:15 2016 -0500 ---------------------------------------------------------------------- src/couch_log_writer_syslog.erl | 155 +++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-couch-log/blob/c572aae6/src/couch_log_writer_syslog.erl ---------------------------------------------------------------------- diff --git a/src/couch_log_writer_syslog.erl b/src/couch_log_writer_syslog.erl new file mode 100644 index 0000000..738d162 --- /dev/null +++ b/src/couch_log_writer_syslog.erl @@ -0,0 +1,155 @@ +% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(couch_log_writer_syslog). +-behavior(couch_log_writer). + + +-export([ + init/0, + terminate/2, + write/2 +]). + + +-include("couch_log.hrl"). + + +-record(st, { + socket, + host, + port, + hostname, + os_pid, + appid, + facility +}). + + +-define(SYSLOG_VERSION, 1). + + +-ifdef(TEST). +-compile(export_all). +-endif. + + +init() -> + {ok, Socket} = gen_udp:open(0), + + SysLogHost = config:get("log", "syslog_host"), + Host = case inet:getaddr(SysLogHost, inet) of + {ok, Address} when SysLogHost /= undefined -> + Address; + _ -> + undefined + end, + + {ok, #st{ + socket = Socket, + host = Host, + port = config:get_integer("log", "syslog_port", 514), + hostname = net_adm:localhost(), + os_pid = os:getpid(), + appid = config:get("log", "syslog_appid", "couchdb"), + facility = get_facility(config:get("log", "syslog_facility", "local2")) + }}. + + +terminate(_Reason, St) -> + gen_udp:close(St#st.socket). + + +write(Entry, St) -> + #log_entry{ + level = Level, + pid = Pid, + msg = Msg, + msg_id = MsgId, + time_stamp = TimeStamp + } = Entry, + Fmt = "<~B>~B ~s ~s ~s ~p ~s - ", + Args = [ + St#st.facility bor get_level(Level), + ?SYSLOG_VERSION, + TimeStamp, + St#st.hostname, + St#st.appid, + Pid, + MsgId + ], + Pre = io_lib:format(Fmt, Args), + ok = send(St, [Pre, Msg, $\n]), + {ok, St}. + + +send(#st{host=undefined}, Packet) -> + io:format(standard_error, "~s", [Packet]); + +send(St, Packet) -> + #st{ + socket = Socket, + host = Host, + port = Port + } = St, + gen_udp:send(Socket, Host, Port, Packet). + + +get_facility(Name) -> + FacId = case Name of + "kern" -> 0; % Kernel messages + "user" -> 1; % Random user-level messages + "mail" -> 2; % Mail system + "daemon" -> 3; % System daemons + "auth" -> 4; % Security/Authorization messages + "syslog" -> 5; % Internal Syslog messages + "lpr" -> 6; % Line printer subsystem + "news" -> 7; % Network news subsystems + "uucp" -> 8; % UUCP subsystem + "clock" -> 9; % Clock daemon + "authpriv" -> 10; % Security/Authorization messages + "ftp" -> 11; % FTP daemon + "ntp" -> 12; % NTP subsystem + "audit" -> 13; % Log audit + "alert" -> 14; % Log alert + "cron" -> 15; % Scheduling daemon + "local0" -> 16; % Local use 0 + "local1" -> 17; % Local use 1 + "local2" -> 18; % Local use 2 + "local3" -> 19; % Local use 3 + "local4" -> 20; % Local use 4 + "local5" -> 21; % Local use 5 + "local6" -> 22; % Local use 6 + "local7" -> 23; % Local use 7 + _ -> + try list_to_integer(Name) of + N when N >= 0, N =< 23 -> N; + _ -> 23 + catch _:_ -> + 23 + end + end, + FacId bsl 3. + + +get_level(Name) when is_atom(Name) -> + case Name of + debug -> 7; + info -> 6; + notice -> 5; + warning -> 4; + error -> 3; + critical -> 2; + alert -> 1; + emergency -> 0; + _ -> 3 + end.
