Skip to content
Browse files

Initial import

  • Loading branch information...
0 parents commit 4ae5aaa19b6486642fe75a7c59003a71cc6b9ae6 @Vagabond committed Sep 23, 2011
Showing with 331 additions and 0 deletions.
  1. +73 −0 bin/bench
  2. BIN rebar
  3. +11 −0 rebar.config
  4. +9 −0 run.sh
  5. +13 −0 src/logbench.app.src
  6. +108 −0 src/logbench.erl
  7. +20 −0 src/logfmt.erl
  8. +97 −0 src/sync_error_logger.erl
73 bin/bench
@@ -0,0 +1,73 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%% vim: set ft=erlang expandtab shiftwidth=4:
+
+main([Bench, Fmt, Iterations]) ->
+ setup_paths(),
+ code:load_file(logbench),
+ code:load_file(logfmt),
+ try {list_to_existing_atom(Bench), list_to_existing_atom(Fmt)} of
+ {BenchMark, Format} ->
+ case erlang:function_exported(logbench, BenchMark, 1) of
+ true ->
+ case erlang:function_exported(logfmt, Format, 0) of
+ true ->
+ run(BenchMark, Format, Iterations);
+ false ->
+ io:format("unknown format ~p~n", [Format]),
+ usage()
+ end;
+ false ->
+ io:format("unknown benchmark ~p~n", [BenchMark]),
+ usage()
+ end
+ catch
+ _:_ ->
+ io:format("no error~n"),
+ usage()
+ end;
+main(_) ->
+ setup_paths(),
+ usage().
+
+run(Bench, Format, Iterations) ->
+ try list_to_integer(Iterations) of
+ Runs ->
+ {Setup, Fun, Stop} = logbench:Bench(logfmt:Format()),
+ Setup(),
+ io:format("running ~p ~p with ~p iterations~n", [Bench, Format, Iterations]),
+ {Time, _} = timer:tc(fun() -> [Fun() || _ <- lists:seq(0, Runs)], Stop() end),
+ Seconds = Time / 1000000,
+ io:format("Result ~p ops/sec ~p~n", [trunc(Runs/Seconds), Seconds]),
+ OutFile = lists:flatten(["results/", atom_to_list(Bench), "_", atom_to_list(Format)]),
+ ok = file:write_file(OutFile, [integer_to_list(trunc(Runs/Seconds)), $\n], [append]),
+ halt(0)
+ catch
+ _:_ ->
+ usage()
+ end.
+
+usage() ->
+ io:format("Usage: ~s <benchmark> <format> <iterations>~n", [filename:basename(escript:script_name())]),
+ Benchmarks = logbench:module_info(exports) -- [{module_info,0},{module_info,1}],
+ io:format("Available benchmarks:~n"),
+ [io:format(" ~s~n", [Bench]) || {Bench, _} <- Benchmarks],
+ Formats = logfmt:module_info(exports) -- [{module_info,0},{module_info,1}],
+ io:format("Available formats:~n"),
+ [io:format(" ~s~n", [Format]) || {Format, _} <- Formats],
+
+ halt(1).
+
+setup_paths() ->
+ true = code:add_pathz(filename:dirname(escript:script_name())
+ ++ "/../ebin"),
+ true = code:add_pathz(filename:dirname(escript:script_name())
+ ++ "/../deps/lager/ebin"),
+ true = code:add_pathz(filename:dirname(escript:script_name())
+ ++ "/../deps/log4erl/ebin"),
+ true = code:add_pathz(filename:dirname(escript:script_name())
+ ++ "/../deps/alog/ebin"),
+ ok.
+
+
+
BIN rebar
Binary file not shown.
11 rebar.config
@@ -0,0 +1,11 @@
+{erl_opts, [debug_info]}.
+
+{cover_enabled, true}.
+
+{deps, [
+ {lager, "0.9.*", {git, "git://github.com/basho/lager", {branch, "master"}}},
+ {log4erl, "0.9.*", {git, "git://github.com/ahmednawras/log4erl.git", {branch, "master"}}},
+ {alog, "1", {git, "git://github.com/siberian-fast-food/alogger.git", {branch, "master"}}}
+ ]
+}.
+
9 run.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+for BENCH in el_console sync_el_console lager_console log4erl_console alog_console el_file sync_el_file lager_file log4erl_file; do
+ for FMT in simple small large; do
+ for I in 1 2 3; do
+ ./bin/bench $BENCH $FMT 10000
+ done
+ done
+done
13 src/logbench.app.src
@@ -0,0 +1,13 @@
+%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 et
+{application, logbench,
+ [
+ {description, "Logger benchmark"},
+ {vsn, "0.1.0"},
+ {modules, []},
+ {applications, [
+ kernel,
+ stdlib
+ ]},
+ {registered, []}
+ ]}.
108 src/logbench.erl
@@ -0,0 +1,108 @@
+-module(logbench).
+
+-compile([{parse_transform, lager_transform}, export_all]).
+
+el_console({Fmt, Args}) ->
+ {fun() -> ok end,
+ fun() -> error_logger:error_msg(Fmt, Args) end,
+ fun() -> _ = gen_event:which_handlers(error_logger) end
+ }.
+
+sync_el_console({Fmt, Args}) ->
+ {fun() -> ok end,
+ fun() -> sync_error_logger:error_msg(Fmt, Args) end,
+ fun() -> ok end
+ }.
+
+lager_console({Fmt, Args}) ->
+ {fun() ->
+ application:load(lager),
+ application:set_env(lager, handlers, [{lager_console_backend, info}]),
+ application:start(lager)
+ end,
+ fun() ->
+ lager:error(Fmt, Args)
+ end,
+ fun() -> ok end
+ }.
+
+log4erl_console({Fmt, Args}) ->
+ {fun() ->
+ application:load(log4erl),
+ application:start(log4erl),
+ log4erl:add_console_appender(cmd_logs, {info, "%j %T [%L] %l%n"})
+ end,
+ fun() ->
+ log4erl:error(Fmt, Args)
+ end,
+ fun() -> ok end
+ }.
+
+alog_console({Fmt, Args}) ->
+ {fun() ->
+ application:start(sasl),
+ application:start(alog),
+ ok = alog_control:delete_all_flows(),
+ ok = alog_control:add_new_flow({mod,['_']}, {'=<', debug}, [alog_tty])
+ end,
+ fun() ->
+ alog:error(Fmt, Args)
+ end,
+ fun() -> ok end
+ }.
+
+el_file({Fmt, Args}) ->
+ {fun() ->
+ error_logger:tty(false),
+ ok = error_logger:logfile({open, "logs/test.log"})
+ end,
+ fun() -> error_logger:error_msg(Fmt, Args) end,
+ fun() -> _ = gen_event:which_handlers(error_logger) end
+ }.
+
+sync_el_file({Fmt, Args}) ->
+ {fun() ->
+ error_logger:tty(false),
+ ok = error_logger:logfile({open, "logs/test.log"})
+ end,
+ fun() -> sync_error_logger:error_msg(Fmt, Args) end,
+ fun() -> ok end
+ }.
+
+lager_file({Fmt, Args}) ->
+ {fun() ->
+ application:load(lager),
+ application:set_env(lager, handlers, [{lager_file_backend, [{"logs/test.log", info}]}]),
+ application:start(lager)
+ end,
+ fun() ->
+ lager:info(Fmt, Args)
+ end,
+ fun() -> ok end
+ }.
+
+log4erl_file({Fmt, Args}) ->
+ {fun() ->
+ application:load(log4erl),
+ application:start(log4erl),
+ log4erl:add_file_appender(cmd_logs, {"logs", "test", {time, 0}, 4, "log", info, "%j %T [%L] %l%n"})
+ end,
+ fun() ->
+ log4erl:error(Fmt, Args)
+ end,
+ fun() -> ok end
+ }.
+
+alog_file({Fmt, Args}) ->
+ {fun() ->
+ application:start(sasl),
+ application:start(alog),
+ ok = alog_control:delete_all_flows(),
+ ok = alog_control:add_new_flow({mod,['_']}, {'=<', debug}, [alog_disk_log])
+ end,
+ fun() ->
+ alog:error(Fmt, Args)
+ end,
+ fun() -> ok end
+ }.
+
20 src/logfmt.erl
@@ -0,0 +1,20 @@
+-module(logfmt).
+
+-compile([export_all]).
+
+simple() ->
+ {"Test~n", []}.
+
+small() ->
+ {"Hello world ~p ~p ~p~n", [node(), self(), now()]}.
+
+large() ->
+ {"Module ~p Function ~p Line ~p: Processes ~p Info ~p~n", [?MODULE, medium, ?LINE, erlang:system_info(process_count), erlang:system_info(info)]}.
+
+giant() ->
+ Bin = binary:copy(<<"a">>, 16777216),
+ {"this is a 16mb binary: ~p~n", [Bin]}.
+
+huge() ->
+ Str = lists:duplicate(4194304, "a"),
+ {"this is a 4mb string: ~p~n", [Str]}.
97 src/sync_error_logger.erl
@@ -0,0 +1,97 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(sync_error_logger).
+
+%% The error_logger API, but synchronous!
+%% This is helpful for tests, otherwise you need lots of nasty timer:sleep.
+%% Additionally, the warning map can be set on a per-process level, for
+%% convienience, via the process dictionary value `warning_map'.
+
+-export([
+ info_msg/1, info_msg/2,
+ warning_msg/1, warning_msg/2,
+ error_msg/1,error_msg/2
+ ]).
+
+-export([
+ info_report/1, info_report/2,
+ warning_report/1, warning_report/2,
+ error_report/1, error_report/2
+ ]).
+
+info_msg(Format) ->
+ info_msg(Format, []).
+
+info_msg(Format, Args) ->
+ gen_event:sync_notify(error_logger, {info_msg, group_leader(), {self(), Format, Args}}).
+
+warning_msg(Format) ->
+ warning_msg(Format, []).
+
+warning_msg(Format, Args) ->
+ gen_event:sync_notify(error_logger, {warning_msg_tag(), group_leader(), {self(), Format, Args}}).
+
+error_msg(Format) ->
+ error_msg(Format, []).
+
+error_msg(Format, Args) ->
+ gen_event:sync_notify(error_logger, {error, group_leader(), {self(), Format, Args}}).
+
+info_report(Report) ->
+ info_report(std_info, Report).
+
+info_report(Type, Report) ->
+ gen_event:sync_notify(error_logger, {info_report, group_leader(), {self(), Type, Report}}).
+
+warning_report(Report) ->
+ warning_report(std_warning, Report).
+
+warning_report(Type, Report) ->
+ {Tag, NType} = warning_report_tag(Type),
+ gen_event:sync_notify(error_logger, {Tag, group_leader(), {self(), NType, Report}}).
+
+error_report(Report) ->
+ error_report(std_error, Report).
+
+error_report(Type, Report) ->
+ gen_event:sync_notify(error_logger, {error_report, group_leader(), {self(), Type, Report}}).
+
+warning_msg_tag() ->
+ case warning_map() of
+ warning -> warning_msg;
+ info -> info_msg;
+ _ -> error
+ end.
+
+warning_report_tag(Type) ->
+ case {warning_map(), Type == std_warning} of
+ {warning, _} -> {warning_report, Type};
+ {info, true} -> {info_report, std_info};
+ {info, false} -> {info_report, Type};
+ {_, true} -> {error_report, std_error};
+ {_, false} -> {error_report, Type}
+ end.
+
+%% get the warning map from the process dictionary first, then the real place.
+warning_map() ->
+ case get(warning_map) of
+ undefined ->
+ error_logger:warning_map();
+ Val -> Val
+ end.

0 comments on commit 4ae5aaa

Please sign in to comment.
Something went wrong with that request. Please try again.