Permalink
Browse files

- Merge trunk with branch tman

  • Loading branch information...
1 parent 0b6319d commit e36f5e4440c4be7c7164cf1ae4156103ad1c0517 caraboides committed Feb 19, 2009
Showing with 23,205 additions and 239 deletions.
  1. +1 −0 AUTHORS
  2. +2 −0 Makefile.in
  3. +4 −0 bin/boot.sh
  4. +2 −2 bin/cs_local.sh
  5. +2 −2 bin/cs_local2.sh
  6. +2 −2 bin/cs_local3.sh
  7. +29 −0 bin/experiments.sh
  8. +29 −8 bin/scalaris.cfg
  9. +40 −0 contrib/log4erl/CHANGELOG.txt
  10. +470 −0 contrib/log4erl/LICENSE.txt
  11. +17 −0 contrib/log4erl/Makefile
  12. +256 −0 contrib/log4erl/README.txt
  13. +18 −0 contrib/log4erl/TODO.txt
  14. +11 −0 contrib/log4erl/ebin/log4erl.app
  15. +46 −0 contrib/log4erl/include/log4erl.hrl
  16. +1 −0 contrib/log4erl/priv/file_logger.conf
  17. +1 −0 contrib/log4erl/priv/logger1.conf
  18. +1 −0 contrib/log4erl/priv/logger2.conf
  19. +46 −0 contrib/log4erl/src/Makefile
  20. +57 −0 contrib/log4erl/src/console_appender.erl
  21. +32 −0 contrib/log4erl/src/dummy_appender.erl
  22. +160 −0 contrib/log4erl/src/file_appender.erl
  23. +219 −0 contrib/log4erl/src/log4erl.erl
  24. +74 −0 contrib/log4erl/src/log4erl_sup.erl
  25. +122 −0 contrib/log4erl/src/log4erl_utils.erl
  26. +217 −0 contrib/log4erl/src/log_formatter.erl
  27. +54 −0 contrib/log4erl/src/log_manager.erl
  28. +56 −0 contrib/log4erl/src/logger_guard.erl
  29. +27 −0 contrib/yaws/LICENSE
  30. BIN contrib/yaws/ebin/authmod_gssapi.beam
  31. BIN contrib/yaws/ebin/haxe.beam
  32. BIN contrib/yaws/ebin/json.beam
  33. BIN contrib/yaws/ebin/jsonrpc.beam
  34. BIN contrib/yaws/ebin/mime_type_c.beam
  35. BIN contrib/yaws/ebin/mime_types.beam
  36. +1 −1 contrib/yaws/ebin/yaws.app
  37. BIN contrib/yaws/ebin/yaws.beam
  38. BIN contrib/yaws/ebin/yaws_404.beam
  39. BIN contrib/yaws/ebin/yaws_api.beam
  40. BIN contrib/yaws/ebin/yaws_app.beam
  41. BIN contrib/yaws/ebin/yaws_appmod_cgi.beam
  42. BIN contrib/yaws/ebin/yaws_cgi.beam
  43. BIN contrib/yaws/ebin/yaws_compile.beam
  44. BIN contrib/yaws/ebin/yaws_config.beam
  45. BIN contrib/yaws/ebin/yaws_ctl.beam
  46. BIN contrib/yaws/ebin/yaws_dav.beam
  47. BIN contrib/yaws/ebin/yaws_debug.beam
  48. BIN contrib/yaws/ebin/yaws_generated.beam
  49. BIN contrib/yaws/ebin/yaws_html.beam
  50. BIN contrib/yaws/ebin/yaws_jsonrpc.beam
  51. BIN contrib/yaws/ebin/yaws_log.beam
  52. BIN contrib/yaws/ebin/yaws_log_file_h.beam
  53. BIN contrib/yaws/ebin/yaws_ls.beam
  54. BIN contrib/yaws/ebin/yaws_pam.beam
  55. BIN contrib/yaws/ebin/yaws_revproxy.beam
  56. BIN contrib/yaws/ebin/yaws_rpc.beam
  57. BIN contrib/yaws/ebin/yaws_rss.beam
  58. BIN contrib/yaws/ebin/yaws_sendfile.beam
  59. BIN contrib/yaws/ebin/yaws_sendfile_compat.beam
  60. BIN contrib/yaws/ebin/yaws_server.beam
  61. BIN contrib/yaws/ebin/yaws_session_server.beam
  62. BIN contrib/yaws/ebin/yaws_soap_lib.beam
  63. BIN contrib/yaws/ebin/yaws_soap_srv.beam
  64. BIN contrib/yaws/ebin/yaws_sup.beam
  65. BIN contrib/yaws/ebin/yaws_sup_restarts.beam
  66. BIN contrib/yaws/ebin/yaws_ticker.beam
  67. BIN contrib/yaws/ebin/yaws_xmlrpc.beam
  68. BIN contrib/yaws/ebin/yaws_zlib.beam
  69. +197 −0 contrib/yaws/src/authmod_gssapi.erl
  70. +938 −0 contrib/yaws/src/haxe.erl
  71. +735 −0 contrib/yaws/src/json.erl
  72. +113 −0 contrib/yaws/src/jsonrpc.erl
  73. +149 −0 contrib/yaws/src/mime_type_c.erl
  74. +679 −0 contrib/yaws/src/mime_types.erl
  75. +2,192 −0 contrib/yaws/src/yaws.erl
  76. +71 −0 contrib/yaws/src/yaws_404.erl
  77. +1,830 −0 contrib/yaws/src/yaws_api.erl
  78. +23 −0 contrib/yaws/src/yaws_app.erl
  79. +14 −0 contrib/yaws/src/yaws_appmod_cgi.erl
  80. +546 −0 contrib/yaws/src/yaws_cgi.erl
  81. +509 −0 contrib/yaws/src/yaws_compile.erl
  82. +1,563 −0 contrib/yaws/src/yaws_config.erl
  83. +2 −0 contrib/yaws/src/yaws_configure.hrl
  84. +168 −0 contrib/yaws/src/yaws_content_negotiation.erl
  85. +473 −0 contrib/yaws/src/yaws_ctl.erl
  86. +547 −0 contrib/yaws/src/yaws_dav.erl
  87. +651 −0 contrib/yaws/src/yaws_debug.erl
  88. +85 −0 contrib/yaws/src/yaws_debug.hrl
  89. +23 −0 contrib/yaws/src/yaws_generated.erl
  90. +282 −0 contrib/yaws/src/yaws_html.erl
  91. +223 −0 contrib/yaws/src/yaws_jsonrpc.erl
  92. +495 −0 contrib/yaws/src/yaws_log.erl
  93. +64 −0 contrib/yaws/src/yaws_log_file_h.erl
  94. +366 −0 contrib/yaws/src/yaws_ls.erl
  95. +290 −0 contrib/yaws/src/yaws_pam.erl
  96. +425 −0 contrib/yaws/src/yaws_revproxy.erl
  97. +320 −0 contrib/yaws/src/yaws_rpc.erl
  98. +500 −0 contrib/yaws/src/yaws_rss.erl
  99. +108 −0 contrib/yaws/src/yaws_sendfile.erl
  100. +88 −0 contrib/yaws/src/yaws_sendfile_compat.erl
  101. +4,181 −0 contrib/yaws/src/yaws_server.erl
  102. +268 −0 contrib/yaws/src/yaws_session_server.erl
  103. +93 −0 contrib/yaws/src/yaws_showarg.erl
  104. +588 −0 contrib/yaws/src/yaws_soap_lib.erl
  105. +235 −0 contrib/yaws/src/yaws_soap_srv.erl
  106. +142 −0 contrib/yaws/src/yaws_sup.erl
  107. +54 −0 contrib/yaws/src/yaws_sup_restarts.erl
  108. +16 −0 contrib/yaws/src/yaws_ticker.erl
  109. +61 −0 contrib/yaws/src/yaws_vdir.erl
  110. +213 −0 contrib/yaws/src/yaws_xmlrpc.erl
  111. +104 −0 contrib/yaws/src/yaws_zlib.erl
  112. +317 −0 contrib/yaws/src/ymnesia.erl
  113. +114 −166 java-api/build.xml
  114. +32 −10 src/admin.erl
  115. +1 −1 src/bench_increment.erl
  116. +2 −1 src/boot_server.erl
  117. +16 −5 src/boot_sup.erl
  118. +1 −1 src/boot_xmlrpc.erl
  119. +4 −0 src/chordsharp.hrl
  120. +4 −4 src/comm_layer/comm_acceptor.erl
  121. +6 −6 src/comm_layer/comm_connection.erl
  122. +8 −2 src/comm_layer/comm_layer.erl
  123. +2 −2 src/comm_layer/comm_port.erl
  124. +13 −3 src/config.erl
  125. +1 −1 src/cs_api.erl
  126. +1 −1 src/cs_db_otp.erl
  127. +4 −4 src/cs_join.erl
  128. +6 −1 src/cs_keyholder.erl
  129. +46 −15 src/cs_node.erl
  130. +6 −1 src/cs_send.erl
Sorry, we could not display the entire diff because it was too big.
View
1 AUTHORS
@@ -5,3 +5,4 @@ Nico Kruber
Jeroen Vlek
Mikael Hoegqvist
Stefan Plantikow
+Christian Hennig
View
2 Makefile.in
@@ -78,6 +78,8 @@ clean:
-rm -rf src/comm_layer/*.beam
-rm -rf src/pubsub/*.beam
-rm -rf src/transstore/*.beam
+ -rm -rf contrib/yaws/ebin/*.beam
+ -rm -rf contrib/log4erl/ebin/*.beam
-rm -rf test/*.beam
-rm -rf doc/*.html
-rm -rf doc/*.css
View
4 bin/boot.sh
@@ -20,4 +20,8 @@ if [ -f "$GLOBAL_CFG" ] ; then source "$GLOBAL_CFG" ; fi
if [ -f "$LOCAL_CFG" ] ; then source "$LOCAL_CFG" ; fi
export ERL_MAX_PORTS=16384
+<<<<<<< .working
erl $ERL_OPTS +A 4 -setcookie "chocolate chip cookie" -pa ../contrib/yaws/ebin -pa ../ebin -yaws embedded true -connect_all false -hidden -sname boot@localhost -s boot
+=======
+erl $ERL_OPTS +S 4 +A 4 -setcookie "chocolate chip cookie" -pa ../contrib/log4erl/ebin -pa ../contrib/yaws/ebin -pa ../ebin -yaws embedded true -connect_all false -sname boot@localhost -s boot
+>>>>>>> .merge-right.r186
View
4 bin/cs_local.sh
@@ -13,8 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-erl -setcookie "chocolate chip cookie" -pa ../contrib/yaws/ebin -pa ../ebin \
- -yaws embedded true -connect_all false -hidden \
+erl +S 4 +A 4 -setcookie "chocolate chip cookie" -pa ../contrib/log4erl/ebin -pa ../contrib/yaws/ebin -pa ../ebin \
+ -yaws embedded true -connect_all false \
-chordsharp cs_port 14196 \
-chordsharp yaws_port 8001 \
-sname node@localhost -s chordsharp
View
4 bin/cs_local2.sh
@@ -13,8 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-erl -setcookie "chocolate chip cookie" -pa ../contrib/yaws/ebin -pa ../ebin \
- -yaws embedded true -connect_all false -hidden \
+erl +S 4 +A 4 -setcookie "chocolate chip cookie" -pa ../contrib/log4erl/ebin -pa ../contrib/yaws/ebin -pa ../ebin \
+ -yaws embedded true -connect_all false \
-chordsharp cs_port 14197 \
-chordsharp yaws_port 8002 \
-sname node2 -s chordsharp
View
4 bin/cs_local3.sh
@@ -13,8 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-erl -setcookie "chocolate chip cookie" -pa ../contrib/yaws/ebin -pa ../ebin \
- -yaws embedded true -connect_all false -hidden \
+erl +S 4 +A 4 -setcookie "chocolate chip cookie" -pa ../contrib/log4erl/ebin -pa ../contrib/yaws/ebin -pa ../ebin \
+ -yaws embedded true -connect_all false \
-chordsharp cs_port 14198 \
-chordsharp yaws_port 8003 \
-sname node3 -s chordsharp
View
29 bin/experiments.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Copyright 2007-2008 Konrad-Zuse-Zentrum für Informationstechnik Berlin
+#
+# 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.
+
+DIRNAME=`dirname $0`
+GLOBAL_CFG="$DIRNAME/scalaris.cfg.sh"
+LOCAL_CFG="$DIRNAME/scalaris.local.cfg.sh"
+if [ -f "$GLOBAL_CFG" ] ; then source "$GLOBAL_CFG" ; fi
+if [ -f "$LOCAL_CFG" ] ; then source "$LOCAL_CFG" ; fi
+
+export ERL_MAX_PORTS=16384
+
+for i in $(seq 1 10); do
+ for i in $(seq 50 50 600); do
+ export RING_SIZE="$i" ;
+ erl $ERL_OPTS +S 4 +A 4 -setcookie "chocolate chip cookie" -pa ../contrib/log4erl/ebin -pa ../contrib/yaws/ebin -pa ../ebin -yaws embedded true -connect_all false -sname boot -s experiments ;
+ done
+done
View
37 bin/scalaris.cfg
@@ -14,23 +14,41 @@
%
% $Id: chordsharp.cfg 494 2008-07-04 17:07:34Z schintke $
+%% DeadNode Cache Parameters
+%% @doc zombieDetectorInterval
+{zombieDetectorInterval,60000}.
-%% @doc the length of the successor list
-{succ_list_length, 10}.
+%% @doc how many dead nodes have to be observed
+{zombieDetectorSize,10}.
+
+%% @doc Loglevel: debug < info < warn < error < fatal < none
+{log_level, warn}.
+
+%% @doc LogFormat, see Readme for log4erl
+%{log_format,"%j %t [%L] %l%n"}.
+{log_format,"[%L] %l%n"}.
+%% @doc the length of the successor list
+{succ_list_length, 9}.
+
+%% @doc the length of the predecessor list
+{pred_list_length, 1}.
%% @doc the number of milliseconds between two failure
%% detector checks
-{failure_detector_interval, 5000}.
+{failure_detector_interval, 2000}.
%% @doc the number of milliseconds between two ping messages
%% several ping messages per failure_detector_interval are possible
-{failure_detector_ping_interval, 2000}.
+{failure_detector_ping_interval, 1000}.
%% @doc the interval between two stabilization runs
-{stabilization_interval, 10000}.
+{stabilization_interval_max, 10000}.
+
+%% @doc the interval between two stabilization runs if T-Man detected a change (only use by rm-tman)
+{stabilization_interval_min, 10000}.
%% @doc the interval between two finger/pointer stabilization runs
-{pointer_stabilization_interval, 5000}.
+{pointer_stabilization_interval, 30000}.
{failure_detector_update_interval, 30000}.
@@ -80,7 +98,7 @@
% cyclon
% cyclon enable
-{cyclon_enable,false}.
+{cyclon_enable,true}.
%cyclon shuffle length
{cyclon_shuffle_length, 4}.
@@ -89,7 +107,7 @@
{cyclon_cache_size, 10}.
%cyclon interval
-{cyclon_interval, 10000}.
+{cyclon_interval, 5000}.
% key_creation algorithm
{key_creator, random}.
@@ -108,3 +126,6 @@
% default assume local testing
{boot_host, {{127,0,0,1},14195,boot}}.
{log_host, {{127,0,0,1},14195,boot_logger}}.
+
+%{boot_host, {boot,'boot@htc026'}}.
+%{log_host, {boot_logger, 'boot@htc026'}}.
View
40 contrib/log4erl/CHANGELOG.txt
@@ -0,0 +1,40 @@
+log4erl 0.8.3:
+==============
+* Added console_appender
+* Added more modifiers to the possible pattern of formats (milliseconds, short/long name of month)
+* Added an extra atom in the tuple argument for add_file_appender/2,3 for specifying format
+
+log4erl 0.8.2:
+==============
+* Fixed issues with log4erl process not part of the supervisor
+* Added support for simple log formatters (similar to Layouts in Log4J)
+* Added change_format/2,3
+* Added change_log_level/1,2
+* Added get_appenders/0,1
+
+Known issues:
+- When file_appender crashes, the format is lost and log4erl will use the
+ default format
+
+log4erl 0.8.1:
+==============
+* Fixed unnecessary formatting of date/time for file_appender
+* Added add_file_appender/2, add_file_appender/3
+* Added add_dummy_appender/2, add_dummy_appender/3
+
+log4erl 0.8:
+============
+* Added the notion of appenders in order to allow different appenders
+for loggers and changed API to reflect this
+* Fixed restarting issues when appenders crash
+* Added dummy_appender for testing multiple appenders
+* Added get_appenders/0,1 function
+
+log4erl 0.7.1:
+==============
+* Changed default behaviour of new file_logger to append in order to preserve previous logs.
+* Changed file_logger_guard.erl to logger_guard.erl because this module will be useful once more
+ logger types are added (e.g. SNMP loggers, Syslog loggers...).
+* Added a function to change log level of loggers during run-time.
+* moved utility functions in file_logger.erl to log4erl_utils.
+* Added log_manager.erl in order to easily allow for more logger types
View
470 contrib/log4erl/LICENSE.txt
@@ -0,0 +1,470 @@
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (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.mozilla.org/MPL/
+
+ 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.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
View
17 contrib/log4erl/Makefile
@@ -0,0 +1,17 @@
+SRC = src
+
+all: subdirs
+
+subdirs:
+ cd ${SRC}; make
+
+# remove all the code
+clean:
+ rm -rf ebin/*.beam erl_crash.dump
+ rm -f *~
+ rm -f src/*~
+ rm -f ebin/*~
+ rm -f include/*~
+# cd dir1; make clean
+#install:
+# cp -f ebin/* ../../www/ebin
View
256 contrib/log4erl/README.txt
@@ -0,0 +1,256 @@
+log4erl Manual:
+===============
+
+TOC:
+====
+1. Features
+2. Installation
+3. Usage
+4. API
+5. Known issues
+6. Future development
+7. License
+
+1. FEATURES:
+============
+- Multiple logs
+- Currently, only size-based log rotation of files for file appender
+- Support default logger if no logger specified
+- 5 predifined log levels (debug, info, warn, error, fatal)
+- Support for user-specified log levels
+- Support for simple log formatter (similar to Layouts in Log4J)
+- Support for console log
+
+2. INSTALLATION:
+================
+To compile & install log4erl, download source from google code's website
+(http://code.google.com/p/log4erl/) or from svn:
+$> svn checkout http://log4erl.googlecode.com/svn/trunk/ log4erl
+$> cd log4erl
+$> make
+
+or you can run the below from erlang shell:
+
+$> cd src
+$> erl
+1> make:all([{outdir, "../ebin"}]).
+
+3. USAGE:
+=========
+1- In order to use log4erl, you need to first include it in the path. There
+are 2 ways to do this:
+a) include the "log4erl" directory in erlang's "lib" directory in the target
+machine (cp -Rf log4erl /where/erlang/is/lib).
+$> cp -Rf log4erl /usr/local/lib/erlang/lib/
+
+b) include the "log4erl" ebin directory in the path when running you program
+$> erl -pz /path/to/log4erl ...
+
+2- Once the log4erl directory is included, you can use its API as described in section "API". but before,
+you need to run:
+> application:start(log4erl).
+
+3- Create loggers & add appenders to them as appropriate. You can do this as per the API below.
+> log4erl:add_logger(messages_log).
+> log4erl:add_file_appender(messages_log, file_logs, Conf).
+ where Conf is the configuration file or erlang term describing how the log is to be handled
+
+4- Additionally, you can change format of file logs
+> log4erl:change_format(messages_log, file_logs, Format).
+ where Format is formatting string as described in API. Note that you can also set the format
+ in the Conf tuple in log4erl:add_file_appender.
+
+5- Now, you can log whatever messages you like as per logging functions described in API.
+
+Precedance of log levels are:
+all = debug < info < warn < error < fatal < none
+User defined levels are always written except when none level is specified in the logger specification
+(See below).
+
+4. API:
+=======
+NOTE:
+-----
+Please be informed that the API below as of now is not stable and any of the functions/parameters below
+may be changed without prior notice.
+
+**> log4erl:add_logger(Name) -> ok | {error, E}
+ Name :: atom() name of the logger
+
+ Example:
+ log4erl:add_logger(chat_logger)
+ This will create a new logger with name 'chat_logger"
+
+**> log4erl:add_file_appender(Name, Spec) -> ok | {error, E}
+ Name :: atom() name of the appender. This value will be used
+ to uniquely references this file appender and can be used to
+ change log level and format of the appended file. This appender
+ will be added to the default_logger
+
+ Spec :: tuple() of the form
+ {LogDir, LogFileName, {size, Size}, NumOfRotations, Suffix, LogLevel}
+ or
+ {LogDir, LogFileName, {size, Size}, NumOfRotations, Suffix, LogLevel, Format}
+ This tuple defines the appender's attributes.
+
+ Example:
+ log4erl:add_file_appender(chat_room1, {"../logs", "room1", {size, 100000}, 4, "txt", warn}).
+ This will directs log4erl to create a file appender and add it to the default
+ logger. all log messages towards default logger will be written to file
+ "../logs/room1.txt". The file will have a size limit of 100000, after which
+ the file will be rotated for 4 times. The log level will be warn, which means
+ info & debug messages will not be written. Format is a list of specifiers. The meanin of these
+ specifiers can be found in description of log4erl:change_format/2 below.
+
+ After suffeciantly long time, the directory "../logs" will look like this:
+ $> ls -l
+ -rw-rw-r-- 1 ahmed ahmed 103845 Jun 25 11:41 logger1_2.elog
+ -rw-rw-r-- 1 ahmed ahmed 102095 Jun 25 11:41 logger1_3.elog
+ -rw-rw-r-- 1 ahmed ahmed 106435 Jun 25 11:41 logger1_4.elog
+ -rw-rw-r-- 1 ahmed ahmed 103390 Jun 25 11:41 logger1_1.elog
+ -rw-rw-r-- 1 ahmed ahmed 7385 Jun 25 11:41 logger1.elog
+
+**> 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_console_appender(Appender, Spec) -> ok
+ log4erl:add_console_appender(Logger, Appender, Spec) -> ok
+ Logger :: atom()
+ Appender :: atom()
+ Spec :: tuple()
+
+ This will create a new console appender to either Logger or default logger and associate spec in Spec to it.
+ Spec is in the form {Level, Format}, which means exactly as it is in file_appender Spec
+
+ Example:
+ log4erl:add_console_appender(cmd_logs, {info, "%j %T [%L] %l%n"}).
+
+**> log4erl:change_log_level(Level) -> ok
+ log4erl:change_log_level(Logger, Level) -> ok
+ Level::atom() = {all, debug, info, error, warn, fatal, none}
+ Logger::atom()
+
+ This will change log level for default logger or named logger to the level
+ specified.
+
+ Example:
+ log4erl:change_log_level(info). %% This will change level of default logger to info
+ log4erl:change_log_level(test_log, warn) %% This will change level of test_log logger to warn
+
+**> log4erl:change_format(Appender, Format) -> ok
+ log4erl:change_format(Logger, Appender, Format) -> ok
+ Appender :: atom()
+ Logger :: atom()
+ Format :: string()
+
+ @since version 0.8.3
+
+ This will change the output format to the specified Format. Format is a pattern string similar to
+ PatternLayout in Log4j. patterns is an arbitrary string with specifiers (proceeded by '%').
+ Possible specifiers are below:
+ d - output date (1-2-2008)
+ j - output date (01-02-2008)
+ t - time (2:13:9)
+ T - time (02:28:01,811637)
+ y - year in YY format (08)
+ Y - year in YYYY format (2008)
+ M - month (2)
+ b - short name of month (Feb)
+ B - long name of month (February)
+ D - day
+ h - hour
+ m - minute
+ s - second
+ i - milli-seconds
+ l - the actual log message
+ L - log level
+ n - new line
+ % - the percentage sign (%)
+
+ Example:
+ log4erl:change_format(file1, "%j %T [%L] %l%n").
+ Will result in the following output (on log4erl:warn("hello"))
+
+ 27-10-2008 15:28:59,98621 [warn] hello
+
+**> log4erl:log(Level, Log) -> ok
+ Level :: atom()
+ Log :: string()
+
+ This will log the text Log to the default logger with level Level.
+
+ Example:
+ log4erl:log(warn, "Hello there").
+ log4erl:log(test_level, "Hello there").
+
+**> log4erl:log(Level, Log, Data) -> ok
+ Level :: atom()
+ Log :: string()
+ Data :: list()
+
+ This will log the text Log to the default logger with level Level and
+ will use Data to format the log text.
+
+ Example:
+ log4erl:log(info, "received message ~p", [Msg]).
+
+**> log4erl:log(Logger, Level, Log, Data) -> ok
+ Logger :: atom()
+ Level :: atom()
+ Log :: string()
+ Data :: list()
+
+ This will log the (Log, Data) to Logger with level Level
+
+ Example:
+ log4erl:log(chat_log, debug, "user entered chat text: ~p", [Chat]).
+
+**> log4erl:Level(Log) -> ok
+ log4erl:Level(Log, Data) -> ok
+ log4erl:Level(Logger, Data) -> ok
+ log4erl:Level(Logger, Log, Data) -> ok
+
+ Level :: warn | info | error | fatal | debug
+ Logger :: atom()
+ Log :: string()
+ Data :: list()
+
+ Exmaple:
+ log4erl:info("This is an info msg").
+ log4erl:warn("Received error ~p",[Msg]).
+ log4erl:fatal(chat_log, "exception occured").
+ log4erl:debug(chat_log, "message received is ~p", [Msg]).
+ log4erl:error("Error").
+
+5. KNOWN ISSUES:
+================
+- Name of both loggers & appenders should be unique and not registered since log4erl will try and register
+ their names. If the name is already registered, nothing will happen. This will be fixed soon.
+- If you run change_log_format/1,2 and appender crashed, a restart from the supervisor will not record the latest
+ format used. It will only use either the default format or the format used in the argument is supplied.
+
+6. FUTURE DEVELOPMENT:
+======================
+- Add support for extensive file-based configuration
+- Add support for different log persistance methods (e.g files, XML, console, DB, SNMP, syslog...etc)
+- Add support for time-based log rotation
+- Multiple configuration format (Erlang terms, XML?, properties files?)
+- Add support for NDC & MDC ???
+
+Please send your suggestion to ahmed.nawras <at @ at> gmail <dot . dot> com
+
+7. LICENSE:
+===========
+This software is subject to "Mozilla Public License 1.1". You can find the license terms
+in the file 'LICENSE.txt' shipping along with the source code. You may also get a copy
+of the license term from the URL: "http://www.mozilla.org/MPL/MPL-1.1.html".
View
18 contrib/log4erl/TODO.txt
@@ -0,0 +1,18 @@
+TODO:
+=====
+
+* Add formatters functions that can be added to appenders to change
+default formatting patters [DONE]
+* Add support for pattern appender [DONE]
+* Update manual [DONE (latest for log4erl 0.8.2)]
+* Add performance benchmarks
+* Add support for file-based configuration to log4erl instead of only
+programmable-only configuration that is working now
+* Add support for SNMP appender
+* Add support for DB appender (MySQL, Postgres?, Mnesia,...etc)
+* Add support for SMTP appender
+* Add support for NT event appender
+* Add support for syslog appender
+* Add support for NDC/MDC
+* Add support for time-based log rotation (file_appender)
+
View
11 contrib/log4erl/ebin/log4erl.app
@@ -0,0 +1,11 @@
+%% This is the application resource file (.app file) for the 'base'
+%% application.
+{application, log4erl,
+[{description, "Logger for erlang in the spirit of Log4J"},
+ {vsn, "0.8.3"},
+ {modules, [log4erl]},
+ {registered,[log4erl]},
+ {applications, [kernel,stdlib]},
+ {mod, {log4erl,[default_logger]}},
+ {start_phases, []}
+]}.
View
46 contrib/log4erl/include/log4erl.hrl
@@ -0,0 +1,46 @@
+-define(ROTATION_CHECK, 10).
+
+-define(DEFAULT_CONF,"log4erl.conf").
+
+-define(DEFAULT_FORMAT, "[%L] %l%n").
+
+-define(DEFAULT_LEVEL, warn).
+
+-define(DEFAULT_LOGGER, default_logger).
+-define(DEFAULT_LOGGER_GUARD, default_logger_guard).
+
+-define(FILE_OPTIONS,[write, raw, binary, append]).
+-define(FILE_OPTIONS_ROTATE,[write, raw, binary]).
+
+%-define(DEBUG, true).
+
+-ifdef(DEBUG).
+-define(LOG(X), io:format("~p: " ++ X,[?MODULE])).
+-define(LOG2(X,D), io:format("~p: " ++ X,[?MODULE | D])).
+-else.
+-define(LOG(_X), ok).
+-define(LOG2(_X,_D), ok).
+-endif.
+
+
+%% type = time | size
+%% max = seconds (for time) | or kiloBytes (for size)
+-record(log_type,{type, max, timer}).
+
+%% file_name = the name of the file without counter
+%% fd = the descriptior for the file
+%% counter = current counter, used for appending to file_name in case of rotation
+%% log_type is a log_type record
+%% rotation = number of rotation before the logger wraps around the coutner (>1)
+%% suffix = suffix of file name (e.g. txt)
+%% The filename of a log is file_name ++ "_" ++ counter ++ "." ++ suffix
+%% e.g. log_1.txt
+%% tokens = format tokens generated from log_formatter:parse/1
+-record(file_appender, {dir, file_name, fd, counter, log_type, rotation, suffix, level, format}).
+
+-record(console_appender, {level, format}).
+
+-record(rotation_state, {state, timer}).
+
+%% log record
+-record(log, {level, msg, data, time, millis}).
View
1 contrib/log4erl/priv/file_logger.conf
@@ -0,0 +1 @@
+{"../logs", "flogger", {size, 10000}, 3, "txt", all}.
View
1 contrib/log4erl/priv/logger1.conf
@@ -0,0 +1 @@
+{"../logs", "logger1", {size, 1000000}, -3, "logs", all}.
View
1 contrib/log4erl/priv/logger2.conf
@@ -0,0 +1 @@
+{"../logs","logger2", {size, 500000}, 2, "elog", all}.
View
46 contrib/log4erl/src/Makefile
@@ -0,0 +1,46 @@
+# leave these lines alone
+.SUFFIXES: .erl .beam .yrl
+
+.erl.beam:
+ erlc -o $(EBIN_DIR) -W $<
+
+.yrl.erl:
+ erlc -o $(EBIN_DIR) -W $<
+
+SOURCE_DIR=src
+EBIN_DIR=../ebin
+INCLUDE_DIR=include
+#SRC=$(wildcard $(SOURCE_DIR)/*)
+ERL = erl -o $(EBIN_DIR) -I ${INCLUDE_DIR}
+SRC = src
+
+# Here's a list of the erlang modules you want compiling
+# If the modules don't fit onto one line add a \ character
+# to the end of the line and continue on the next line
+# Edit the lines below
+MODS = log4erl_sup log4erl file_appender console_appender log_manager logger_guard log4erl_utils dummy_appender log_formatter
+
+all: compile
+
+#compile: ${MODS:%=%.beam} #application
+#compile: ${SRC}/${MODS:%=%.beam}
+compile: ${MODS:%=%.beam}
+
+## special compilation requirements are added here
+#.beam:
+# ${ERL} -W0 *.erl
+
+application: compile
+# ${ERL} -pa ebin -o ${EBIN_DIR} -s application start Arg1 Arg2
+
+run:
+ ${ERL} -pa ebin -s test test
+# the subdirs target compiles any code in
+# sub-directories
+#subdirs:
+# cd dir1; make
+
+# remove all the code
+clean:
+ rm -rf ../ebin/*.beam erl_crash.dump
+# cd dir1; make clean
View
57 contrib/log4erl/src/console_appender.erl
@@ -0,0 +1,57 @@
+-module(console_appender).
+
+-include("../include/log4erl.hrl").
+
+-behaviour(gen_event).
+%% gen_event callbacks
+-export([init/1, handle_event/2, handle_call/2,
+ handle_info/2, terminate/2, code_change/3]).
+
+init({Level}) ->
+ init({Level, ?DEFAULT_FORMAT});
+init({Level, Format} = _Args) ->
+ ?LOG2("Initializing console_appender with args = ~p~n",[_Args]),
+ {ok, Toks} = log_formatter:parse(Format),
+ ?LOG2("Tokens received is ~p",[Toks]),
+ State = #console_appender{level = Level, format = Toks},
+ ?LOG2("State is ~p",[State]),
+ {ok, State}.
+
+handle_event({change_level, Level}, State) ->
+ State2 = State#console_appender{level = Level},
+ ?LOG2("Changed level to ~p~n",[Level]),
+ {ok, State2};
+handle_event({log,LLog}, State) ->
+ ?LOG2("handl_event:log = ~p~n",[LLog]),
+ do_log(LLog, State),
+ {ok, State}.
+
+handle_call({change_format, Format}, State) ->
+ ?LOG2("Old State in console_appender is ~p~n",[State]),
+ {ok, Tokens} = log_formatter:parse(Format),
+ ?LOG2("Adding format of ~p~n",[Tokens]),
+ State1 = State#console_appender{format=Tokens},
+ {ok, ok, State1};
+handle_call(_Request, State) ->
+ Reply = ok,
+ {ok, Reply, State}.
+
+handle_info(_Info, State) ->
+ {ok, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+do_log(#log{level = L} = Log,#console_appender{level=Level, format=Format}) ->
+ ToLog = log4erl_utils:to_log(L, Level),
+ case ToLog of
+ true ->
+ M = log_formatter:format(Log, Format),
+ ?LOG2("console_appender result message is ~s~n",[M]),
+ io:format(M);
+ false ->
+ ok
+ end.
View
32 contrib/log4erl/src/dummy_appender.erl
@@ -0,0 +1,32 @@
+-module(dummy_appender).
+
+-include("../include/log4erl.hrl").
+
+-behaviour(gen_event).
+%% gen_event callbacks
+-export([init/1, handle_event/2, handle_call/2,
+ handle_info/2, terminate/2, code_change/3]).
+
+-record(state, {}).
+
+init(_Args) ->
+ io:format("Initializing dummy_appender with args = ~p~n",[_Args]),
+ {ok, #state{}}.
+
+handle_event(_Event, State) ->
+ io:format("dummy_appender received event ~p~n",[_Event]),
+ {ok, State}.
+
+handle_call(_Request, State) ->
+ Reply = ok,
+ {ok, Reply, State}.
+
+handle_info(_Info, State) ->
+ {ok, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
View
160 contrib/log4erl/src/file_appender.erl
@@ -0,0 +1,160 @@
+-module(file_appender).
+
+-author("Ahmed Al-Issaei").
+-license("MPL-1.1").
+
+-behaviour(gen_event).
+
+-include("../include/log4erl.hrl").
+-include_lib("kernel/include/file.hrl").
+
+%% gen_event callbacks
+-export([init/1, handle_event/2, handle_call/2,
+ handle_info/2, terminate/2, code_change/3]).
+
+%%======================================
+%% gen_event callback functions
+%%======================================
+init({Dir, Fname, {Type, Max}, Rot, Suf, Level})->
+ ?LOG("file_appender:init() - with default format~n"),
+ init({Dir, Fname, {Type, Max}, Rot, Suf, Level, ?DEFAULT_FORMAT});
+%% This one with custom format
+init({Dir, Fname, {Type, Max}, Rot, Suf, Level, Pattern} = _Conf) ->
+ ?LOG("file_appender:init() - 1~n"),
+ File = Dir ++ "/" ++ Fname ++ "." ++ Suf,
+ {ok, Fd} = file:open(File, ?FILE_OPTIONS),
+ Ltype = #log_type{type = Type, max = Max},
+ % Check Rot >= 0
+ Rot1 = case Rot < 0 of
+ true ->
+ 0;
+ false ->
+ Rot
+ end,
+ ?LOG2("To parse format with customer format ~p~n",[Pattern]),
+ {ok, Format} = log_formatter:parse(Pattern),
+ ?LOG2("Adding format of ~p~n",[Format]),
+ State = #file_appender{dir = Dir, file_name = Fname, fd = Fd, counter=0,
+ log_type = Ltype, rotation = Rot1, suffix=Suf,
+ level=Level, format=Format},
+ ?LOG2("file_appender:init() with conf ~p~n",[State]),
+ {ok, State};
+init(Conf) when is_list(Conf) ->
+ ?LOG2("file_appender:init() ~p~n",[Conf]),
+ case file:consult(Conf) of
+ {error, Reason} ->
+ error_logger:error_msg("file_appender: couldn't consult Conf file~n"),
+ {error, file:format_error(Reason)};
+ {ok, [Terms]} ->
+ init(Terms)
+ end;
+init(_N) ->
+ ?LOG2("file_appender:init() with parameter ~p~n",[_N]),
+ {ok, #file_appender{}}.
+
+handle_event({change_level, Level}, State) ->
+ State2 = State#file_appender{level = Level},
+ ?LOG2("Changed level to ~p~n",[Level]),
+ {ok, State2};
+handle_event({log,LLog}, State) ->
+ ?LOG2("handl_event:log = ~p~n",[LLog]),
+ do_log(LLog, State),
+ Res = check_rotation(State),
+ {ok, Res}.
+
+
+handle_call({change_format, Format}, State) ->
+ ?LOG2("Old State in file_appender is ~p~n",[State]),
+ {ok, Tokens} = log_formatter:parse(Format),
+ ?LOG2("Adding format of ~p~n",[Tokens]),
+ State1 = State#file_appender{format=Tokens},
+ {ok, ok, State1};
+handle_call(_Request, State) ->
+ Reply = ok,
+ {ok, Reply, State}.
+
+handle_info(_Info, State) ->
+ ?LOG2("~w received unknown message: ~p~n", [?MODULE, _Info]),
+ {ok, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%======================================
+%% internal callback functions
+%%======================================
+do_log(#log{level = L} = Log,#file_appender{fd = Fd, level=Level, format=Format} = _State) when is_atom(L) ->
+ ?LOG2("Formatting ~p~n",[Format]),
+ ToLog = log4erl_utils:to_log(L, Level),
+ case ToLog of
+ true ->
+ M = log_formatter:format(Log, Format),
+ file:write(Fd, M);
+ false ->
+ ok
+ end;
+do_log(_Other, _State) ->
+ ?LOG2("unknown level ~p~n",[_Other]),
+ ok.
+
+rotate(#file_appender{fd = Fd, dir=Dir, file_name=Fn, counter=Cntr, rotation=Rot, suffix=Suf, log_type=Ltype, level=Level} = _S) ->
+ file:close(Fd),
+ ?LOG("Starting rotation~n"),
+ C = if
+ Rot == 0 ->
+ 0;
+ Cntr >= Rot ->
+ 1;
+ true ->
+ Cntr+1
+ end,
+ Src = Dir ++ "/" ++ Fn ++ "." ++ Suf,
+ Fname = case C of
+ 0 ->
+ Dir ++ "/" ++ Fn ++ "." ++ Suf;
+ _ ->
+ Dir ++ "/" ++ Fn ++ "_" ++ integer_to_list(C) ++ "." ++ Suf
+ end,
+ ?LOG2("Renaming file from ~p to ~p~n",[Src, Fname]),
+ file:copy(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},
+ {ok, State2}.
+
+% Check if the file needs to be rotated
+% ignore in case of if log type is set to time instead of size
+check_rotation(State) ->
+ #file_appender{dir=Dir, file_name=Fname, log_type = #log_type{type=T, max=Max}, suffix=Suf} = State,
+ case T of
+ size ->
+ File = Dir ++ "/" ++ Fname ++ "." ++ Suf,
+ {ok, Finfo} = file:read_file_info(File),
+ Size = Finfo#file_info.size,
+ if
+ Size > Max ->
+ {ok, State2} = rotate(State),
+ State2;
+ true ->
+ State
+ end;
+ %% time-based rotation is not implemented yet
+ _ ->
+ State
+ end.
+
+%% format_log(L, T, Log, Data) ->
+%% T2 = log4erl_utils:get_current_time(T),
+%% L2 = log4erl_utils:gen_log_txt(atom_to_list(L)),
+%% F = fun(X, A) ->
+%% case is_atom(X) of
+%% true ->
+%% A ++ atom_to_list(X);
+%% _ ->
+%% A ++ X
+%% end
+%% end,
+%% Msg = lists:foldl(F, "", [T2," ",L2," ",Log,"~n"]),
+%% io_lib:format(Msg,Data).
View
219 contrib/log4erl/src/log4erl.erl
@@ -0,0 +1,219 @@
+-module(log4erl).
+
+-author("Ahmed Al-Issaei").
+-license("MPL-1.1").
+
+-behaviour(gen_server).
+-behaviour(application).
+
+-include("../include/log4erl.hrl").
+
+%% API
+-export([start_link/1]).
+
+-export([change_log_level/1, change_log_level/2]).
+-export([add_logger/1]).
+-export([add_appender/2, add_appender/3]).
+-export([add_file_appender/2, add_file_appender/3]).
+-export([add_console_appender/2, add_console_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([log/2, log/3, log/4]).
+
+-export([warn/1, warn/2, warn/3]).
+-export([info/1, info/2, info/3]).
+-export([error/1, error/2, error/3]).
+-export([fatal/1, fatal/2, fatal/3]).
+-export([debug/1, debug/2, debug/3]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+start_link(Default_logger) ->
+ %log4erl_sup:add_logger(Default_logger),
+ ?LOG("Starting process log4erl"),
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [Default_logger], []).
+
+add_logger(Logger) ->
+ try_msg({add_logger, Logger}).
+
+%% Appender = {Appender, Name}
+add_appender(Appender, Conf) ->
+ try_msg({add_appender, Appender, Conf}).
+
+%% Appender = {Appender, Name}
+add_appender(Logger, Appender, Conf) ->
+ try_msg({add_appender, Logger, Appender, Conf}).
+
+add_console_appender(AName, Conf) ->
+ add_appender({console_appender, AName}, Conf).
+
+add_console_appender(Logger, AName, Conf) ->
+ add_appender(Logger, {console_appender, AName}, Conf).
+
+add_file_appender(AName, Conf) ->
+ add_appender({file_appender, AName}, Conf).
+
+add_file_appender(Logger, AName, Conf) ->
+ add_appender(Logger, {file_appender, AName}, Conf).
+
+add_dummy_appender(AName, Conf) ->
+ add_appender({dummy_appender, AName}, Conf).
+
+add_dummy_appender(Logger, AName, Conf) ->
+ add_appender(Logger, {dummy_appender, AName}, Conf).
+
+get_appenders() ->
+ try_msg(get_appenders).
+
+get_appenders(Logger) ->
+ try_msg({get_appenders, Logger}).
+
+change_format(Appender, Format) ->
+ try_msg({change_format, Appender, Format}).
+change_format(Logger, Appender, Format) ->
+ try_msg({change_format, Logger, Appender, Format}).
+
+%% For default logger
+change_log_level(Level) ->
+ try_msg({change_level, Level}).
+change_log_level(Logger, Level) ->
+ try_msg({change_level, Logger, Level}).
+
+try_msg(Msg) ->
+ try
+ gen_server:call(?MODULE, Msg)
+ catch
+ exit:{noproc, _M} ->
+ io:format("log4erl has not been initialized yet. To do so, please run~n"),
+ io:format("> application:start(log4erl).~n"),
+ {error, log4erl_not_started};
+ E:M ->
+ ?LOG2("Error message received by log4erl is ~p:~p~n",[E, M]),
+ {E, M}
+ end.
+
+log(Level, Log) ->
+ log(Level, Log, []).
+log(Level, Log, Data) ->
+ try_msg({log, Level, Log, Data}).
+log(Logger, Level, Log, Data) ->
+ try_msg({log, Logger, Level, Log, Data}).
+
+warn(Log) ->
+ log(warn, Log).
+%% If 1st parameter is atom, then it is Logger
+warn(Logger, Log) when is_atom(Logger) ->
+ log(Logger, warn, Log, []);
+warn(Log, Data) ->
+ log(warn, Log, Data).
+warn(Logger, Log, Data) ->
+ log(Logger, warn , Log, Data).
+
+info(Log) ->
+ log(info, Log).
+info(Logger, Log) when is_atom(Logger) ->
+ log(Logger, info, Log, []);
+info(Log, Data) ->
+ log(info, Log, Data).
+info(Logger, Log, Data) ->
+ log(Logger, info, Log, Data).
+
+error(Log) ->
+ log(error, Log).
+error(Logger, Log) when is_atom(Logger) ->
+ log(Logger, error, Log, []);
+error(Log, Data) ->
+ log(error, Log, Data).
+error(Logger, Log, Data) ->
+ log(Logger, error, Log, Data).
+
+fatal(Log) ->
+ log(fatal, Log).
+fatal(Logger, Log) when is_atom(Logger) ->
+ log(Logger, fatal, Log, []);
+fatal(Log, Data) ->
+ log(fatal, Log, Data).
+fatal(Logger, Log, Data) ->
+ log(Logger, fatal, Log, Data).
+
+debug(Log) ->
+ log(debug, Log).
+debug(Logger, Log) when is_atom(Logger) ->
+ log(Logger, debug, Log, []);
+debug(Log, Data) ->
+ log(debug, Log, Data).
+debug(Logger, Log, Data) ->
+ log(Logger, debug, Log, Data).
+
+%%======================================
+%% gen_server callback functions
+%%======================================
+init([Default_logger]) ->
+ ?LOG2("starting log4erl server with default_logger ~p~n",[Default_logger]),
+ {ok, {default_logger, Default_logger}}.
+
+%% No logger specified? use default logger
+handle_call({add_logger, Logger}, _From, State) ->
+ log_manager:add_logger(Logger),
+ {reply, ok, State};
+handle_call({add_appender, Appender, Conf}, _From, {default_logger, DL} = State) ->
+ log_manager:add_appender(DL, Appender, Conf),
+ {reply, ok, State};
+handle_call({add_appender, Logger, Appender, Conf}, _From, State) ->
+ log_manager:add_appender(Logger, Appender, Conf),
+ {reply, ok, State};
+handle_call(get_appenders, _From, {default_logger, DL} = State) ->
+ Reply = gen_event:which_handlers(DL),
+ {reply, Reply, State};
+handle_call({get_appenders, Logger}, _From, State) ->
+ Reply = gen_event:which_handlers(Logger),
+ {reply, Reply, State};
+handle_call({change_level, Level}, _From, {default_logger, DL} = State) ->
+ log_manager:change_level(DL, Level),
+ {reply, ok, State};
+handle_call({change_level, Logger, Level}, _From, State) ->
+ log_manager:change_level(Logger, Level),
+ {reply, ok, State};
+handle_call({change_format, Appender, Format}, _From, {default_logger,DL} = State) ->
+ log_manager:change_format(DL, Appender, Format),
+ {reply, ok, State};
+handle_call({change_format, Logger, Appender, Format}, _From, State) ->
+ log_manager:change_format(Logger, Appender, Format),
+ {reply, ok, State};
+handle_call({log, Level, Log, Data}, _From, {default_logger, Logger} = State) ->
+ log_manager:log(Logger, Level, Log, Data),
+ {reply, ok, State};
+handle_call({log, Logger, Level, Log, Data} , _From, State) ->
+ log_manager:log(Logger, Level, Log, Data),
+ {reply, ok, State}.
+
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%======================================
+%% application callback functions
+%%======================================
+start(_Type, [Arg]) ->
+ ?LOG("Starting log4erl app~n"),
+ log4erl_sup:start_link(Arg).
+
+stop(_State) ->
+ ok.
+
+
View
74 contrib/log4erl/src/log4erl_sup.erl
@@ -0,0 +1,74 @@
+-module(log4erl_sup).
+
+-author("Ahmed Al-Issaei").
+-license("MPL-1.1").
+
+-behaviour(supervisor).
+
+-include("../include/log4erl.hrl").
+
+%% API
+-export([start_link/1]).
+-export([add_logger/1]).
+-export([add_guard/4]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+start_link(Default_logger) ->
+ R = supervisor:start_link({local, ?MODULE}, ?MODULE, [Default_logger]),
+ %log4erl:start_link(Default_logger),
+ add_logger(Default_logger),
+ ?LOG2("Result in supervisor is ~p~n",[R]),
+ R.
+
+add_guard(Logger, Appender, Name, Conf) ->
+ C = {Name,
+ {logger_guard, start_link ,[Logger, Appender, Name, Conf]},
+ permanent,
+ 10000,
+ worker,
+ [logger_guard]},
+ ?LOG2("Adding ~p to ~p~n",[C, ?MODULE]),
+ supervisor:start_child(?MODULE, C).
+
+add_logger(Name) when is_atom(Name) ->
+ N = atom_to_list(Name),
+ add_logger(N);
+add_logger(Name) when is_list(Name) ->
+ C1 = {Name,
+ {log_manager, start_link ,[Name]},
+ permanent,
+ 10000,
+ worker,
+ [log_manager]},
+
+ ?LOG2("Adding ~p to ~p~n",[C1, ?MODULE]),
+ supervisor:start_child(?MODULE, C1).
+ %add_guard(N2).
+
+%%======================================
+%% supervisor callback functions
+%%======================================
+init([Default_logger]) ->
+ ?LOG("Starting supervisor~n"),
+ %% No children to be added yet.
+ %% The default has to be added from log4erl
+
+ % start log4erl gen_server
+ _Child = {log4erl_p,
+ {log4erl, start_link ,[Default_logger]},
+ permanent,
+ 10000,
+ worker,
+ [log4erl]},
+
+ {ok,
+ {
+ {one_for_one,3,10},
+ [_Child]
+ %[]
+ }
+ }.
+
+
View
122 contrib/log4erl/src/log4erl_utils.erl
@@ -0,0 +1,122 @@
+-module(log4erl_utils).
+
+-export([gen_log_txt/1,return_2columns/1, get_current_time/1, to_log/2]).
+-export([get_id/0, get_month_name/1, get_month_long_name/1]).
+
+% a function to make the log level text look pretty
+gen_log_txt(L) when is_list(L) ->
+ case string:len(L) of
+ 1 ->
+ "[" ++ L ++ "] ";
+ 2 ->
+ "[" ++ L ++ "] ";
+ 3 ->
+ "[" ++ L ++ "] ";
+ 4 ->
+ "[" ++ L ++ "] ";
+ _ ->
+ "[" ++ L ++ "]"
+ end.
+
+% a function to format date/time properly (e.g. 09 instead of 9)
+return_2columns(X) ->
+ case length(X) of
+ 1 ->
+ "0" ++ X;
+ _ ->
+ X
+ end.
+
+% returns date/time as a properly formatted string (e.g. "01-01-2000 12:12:12")
+%get_current_time() ->
+get_current_time({{Y, M, D}, {H, Mi, S}}) ->
+ %{{Y, M, D}, {H, Mi, S}} = calendar:local_time(),
+ L = lists:map(fun(X) ->
+ X2=integer_to_list(X),
+ return_2columns(X2)
+ end,
+ [Y, M, D, H, Mi, S]
+ ),
+ [Y2, M2, D2, H2, Mi2, S2] = L,
+ Y2 ++ "-" ++ M2 ++ "-" ++ D2 ++ " " ++ H2 ++ ":" ++ Mi2 ++ ":" ++ S2.
+
+%% DEBUG <- INFO <- WARN <- ERROR <- FATAL
+%% user defined levels are always logged
+to_log(Cur, Level) ->
+ case Level of
+ debug ->
+ true;
+ info ->
+ ((Cur == info) or (Cur == warn) or (Cur == error) or (Cur == fatal));
+ warn ->
+ ((Cur == warn) or (Cur == error) or (Cur == fatal));
+ error ->
+ ((Cur == error) or (Cur == fatal));
+ fatal ->
+ (Cur == fatal);
+ none ->
+ false;
+ _ ->
+ true
+ end.
+
+get_id() ->
+ {_,_,N} = now(),
+ Id = "log4erl_" ++ integer_to_list(random:uniform(N)),
+ list_to_atom(Id).
+
+get_month_name(Month) ->
+ case Month of
+ 1 ->
+ "Jan";
+ 2 ->
+ "Feb";
+ 3 ->
+ "Mar";
+ 4 ->
+ "Apr";
+ 5 ->
+ "May";
+ 6 ->
+ "Jun";
+ 7 ->
+ "Jul";
+ 8 ->
+ "Aug";
+ 9 ->
+ "Sep";
+ 10 ->
+ "Oct";
+ 11 ->
+ "Nov";
+ 12 ->
+ "Dec"
+ end.
+
+get_month_long_name(Month) ->
+ case Month of
+ 1 ->
+ "January";
+ 2 ->
+ "February";
+ 3 ->
+ "March";
+ 4 ->
+ "April";
+ 5 ->
+ "May";
+ 6 ->
+ "June";
+ 7 ->
+ "July";
+ 8 ->
+ "August";
+ 9 ->
+ "September";
+ 10 ->
+ "October";
+ 11 ->
+ "November";
+ 12 ->
+ "December"
+ end.
View
217 contrib/log4erl/src/log_formatter.erl
@@ -0,0 +1,217 @@
+-module(log_formatter).
+
+-compile(export_all).
+
+-include("../include/log4erl.hrl").
+
+%-record(log, {level, msg, data, time}).
+
+test() ->
+ Log = #log{level = warn,
+ msg = "logging message for testing purposes ~p",
+ data = [tt],
+ time = calendar:local_time()},
+ %Ts = "%j %T [%L] - %l %n",
+ Ts = "[%L] %l%n",
+ {ok, Tokens} = parse(Ts),
+ T = format(Log, Tokens),
+ io:format("~s",[T]).
+
+test2(Num) ->
+ Ts = "%j %T [%L] - %l",
+ {ok, Tokens} = parse(Ts),
+ Logs = lists:map(fun(X) ->
+ {X, make_log(warn, "testing a lot", [])}
+ end,
+ lists:seq(1, Num)),
+ lists:map(fun(X) ->
+ N = element(1,X),
+ X1 = element(2, X),
+ X2 = format(X1, Tokens),
+ io:format("~p: ~s~n",[N, X2])
+ end, Logs),
+ ok.
+
+make_log(Level, Msg, Data) ->
+ #log{level = Level,
+ msg = Msg,
+ data = Data,
+ time = calendar:local_time()}.
+
+
+%%%%%%%%%%%%%%%%%%%
+%% functions
+%%%%%%%%%%%%%%%%%%%
+format(Log, Tokens) ->
+ ?LOG2("log_formatter formatting log: ~p~n",[Log]),
+ F = fun(X) ->
+ M = get_token_value(X,Log),
+ M
+ end,
+ L = lists:map(F, Tokens),
+ L.
+
+get_token_value(date, Log) ->
+ D = Log#log.time,
+ {{Y, M, Dd},_} = D,
+ [C,B,A] = lists:map(
+ fun(X) ->
+
+ integer_to_list(X)
+ end,
+ [Y,M,Dd]),
+ Res = A ++ "-" ++ B ++ "-" ++ C,
+ Res;
+get_token_value(date2, Log) ->
+ D = Log#log.time,
+ {{Y, M, Dd},_} = D,
+ [C,B,A] = lists:map(
+ fun(X) ->
+ X2 = integer_to_list(X),
+ case string:len(X2) > 1 of
+ false ->
+ "0" ++ X2;
+ _ ->
+ X2
+ end
+ end,
+ [Y,M,Dd]),
+ Res = A ++ "-" ++ B ++ "-" ++ C,
+ Res;
+get_token_value(time, Log) ->
+ D = Log#log.time,
+ {_,{H, M, S}} = D,
+ [A,B,C] = lists:map(
+ fun(X) ->
+ integer_to_list(X)
+ end,
+ [H,M,S]),
+ Res = A ++ ":" ++ B ++ ":" ++ C,
+ Res;
+get_token_value(time2, Log) ->
+ D = Log#log.time,
+ Ms = Log#log.millis,
+ {_,{H, M, S}} = D,
+ [A,B,C,E] = lists:map(
+ fun(X) ->
+ X2 = integer_to_list(X),
+ case string:len(X2) > 1 of
+ false ->
+ "0" ++ X2;
+ _ ->
+ X2
+ end
+ end,
+ [H,M,S, Ms]),
+ Res = A ++ ":" ++ B ++ ":" ++ C ++ "," ++ E,
+ Res;
+get_token_value(year4, Log) ->
+ D = Log#log.time,
+ {{Y, _,_},_} = D,
+ integer_to_list(Y);
+get_token_value(year2, Log) ->
+ D = Log#log.time,
+ {{Y, _,_},_} = D,
+ L = integer_to_list(Y),
+ string:substr(L,3,2);
+get_token_value(month, Log) ->
+ {{_, M,_},_} = Log#log.time,
+ integer_to_list(M);
+get_token_value(month2, Log) ->
+ {{_,M,_},_} = Log#log.time,
+ log4erl_utils:get_month_name(M);
+get_token_value(month3, Log) ->
+ {{_, M,_},_} = Log#log.time,
+ log4erl_utils:get_month_long_name(M);
+get_token_value(day, Log) ->
+ D = Log#log.time,
+ {{_, _,Dd},_} = D,
+ integer_to_list(Dd);
+get_token_value(hour, Log) ->
+ D = Log#log.time,
+ {_,{H, _,_}} = D,
+ integer_to_list(H);
+get_token_value(minute, Log) ->
+ D = Log#log.time,
+ {_,{_, M,_}} = D,
+ integer_to_list(M);
+get_token_value(second, Log) ->
+ D = Log#log.time,
+ {_,{_, _,S}} = D,
+ integer_to_list(S);
+get_token_value(millis, Log) ->
+ Ms = Log#log.millis,
+ integer_to_list(Ms);
+get_token_value(log, Log) ->
+ Msg = Log#log.msg,
+ Data = Log#log.data,
+ io_lib:format(Msg, Data);
+get_token_value(level, Log) ->
+ atom_to_list(Log#log.level);
+get_token_value(new_line, _Log) ->
+ "\n";
+get_token_value(A, _Log) ->
+ A.
+
+%%%%%%%%%%%%%%%%%%%
+%% parse functions
+%%%%%%%%%%%%%%%%%%%
+parse(M) ->
+ ?LOG2("log_formatter parsing ~p~n",[M]),
+ try
+ Tokens = parse2(M,[]),
+ ?LOG2("Received tokens ~p~n",[Tokens]),
+ {ok, Tokens}
+ catch
+ E:R ->
+ {error, {E,R}}
+ end.
+
+parse2([], Acc) ->
+ lists:reverse(Acc);
+parse2([$\% | R], Acc) ->
+ [S|R2] = R,
+ T = parse_char(S),
+ parse2(R2,[T|Acc]);
+parse2([S | R], Acc) ->
+ parse2(R, [S|Acc]).
+
+parse_char($d) ->
+ date;
+parse_char($j) ->
+ date2;
+parse_char($t) ->
+ time;
+parse_char($T) ->
+ time2;
+parse_char($y) ->
+ year2;
+parse_char($Y) ->
+ year4;
+% 1
+parse_char($M) ->
+ month;
+% Jan
+parse_char($b) ->
+ month2;
+% January
+parse_char($B) ->
+ month3;
+parse_char($D) ->
+ day;
+parse_char($h) ->
+ hour;
+parse_char($m) ->
+ minute;
+parse_char($s) ->
+ second;
+parse_char($l) ->
+ log;
+parse_char($L) ->
+ level;
+parse_char($n) ->
+ new_line;
+parse_char($i) ->
+ millis;
+parse_char(C) ->
+ C.
View
54 contrib/log4erl/src/log_manager.erl
@@ -0,0 +1,54 @@
+-module(log_manager).
+
+-author("Ahmed Al-Issaei").
+-license("MPL-1.1").
+
+-include("../include/log4erl.hrl").
+
+%% API
+-export([start_link/1]).
+-export([change_level/2]).
+-export([add_logger/1]).
+-export([add_appender/3]).
+-export([change_format/3]).
+-export([log/4]).
+
+start_link(Logger) when is_atom(Logger) ->
+ ?LOG2("log_manager adding Logger ~p~n",[Logger]),
+ gen_event:start_link({local, Logger});
+start_link(Logger) when is_list(Logger) ->
+ ?LOG2("log_manager adding Logger ~p~n",[Logger]),
+ gen_event:start_link({local, list_to_atom(Logger)}).
+
+add_logger(Logger) ->
+ log4erl_sup:add_logger(Logger).
+
+add_appender(Logger, {Appender, Name} , Conf) ->
+ ?LOG2("add_appender ~p with name ~p to ~p with Conf ~p ~n",[Appender, Name, Logger, Conf]),
+ log4erl_sup:add_guard(Logger, Appender, Name, Conf).
+
+change_level(Logger, Level) ->
+ gen_event:notify(Logger, {change_level, Level}).
+
+change_format(Logger, Appender, Format) ->
+ Apps = gen_event:which_handlers(Logger),
+ ?LOG2("log_manager:change_format/3 get apps ~p~n",[Apps]),
+ [Apps1] = lists:filter(fun({_,X}) -> X =:= Appender end, Apps),
+ ?LOG2("get apps: ~p~n",[Apps1]),
+ gen_event:call(Logger, Apps1, {change_format, Format}).
+
+%%--------------------------------------------------------------------
+%% Logger API functions
+%%--------------------------------------------------------------------
+log(Logger, Level, Log, Data) ->
+ T = calendar:local_time(),
+ {_, _, Ms} = erlang:now(),
+ ?LOG2("Logging:~n ~p ~p ~p ~p~n",[Logger, Level, Log, Data]),
+ LL = #log{level=Level, msg=Log, data=Data, time=T, millis = Ms},
+ try
+ gen_event:notify(Logger, {log, LL})
+ catch
+ _E:_R ->
+ ?LOG2("log_manager:log error ~p:~p~n",[_E,_R])
+ end.
+
View
56 contrib/log4erl/src/logger_guard.erl
@@ -0,0 +1,56 @@
+-module(logger_guard).
+
+-author("Ahmed Al-Issaei").
+-license("MPL-1.1").
+
+-behaviour(gen_server).
+
+-include("../include/log4erl.hrl").
+
+%% API
+-export([start_link/4, add_sup_handler/3]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+start_link(Logger, Appender, Name, Conf) ->
+ %?LOG2("starting guard for logger ~p~n",[Logger]),
+ {ok, Pid} = gen_server:start_link(?MODULE, [Appender, Name], []),
+ add_sup_handler(Pid, Logger, Conf),
+ {ok, Pid}.
+
+add_sup_handler(G_pid, Logger, Conf) ->
+ ?LOG("add_sup()~n"),
+ gen_server:call(G_pid, {add_sup_handler, Logger, Conf}).
+
+%%=========================================
+%% gen_server callback functions
+%%=========================================
+init([Appender, Name]) ->
+ ?LOG2("Starting guard ~n",[]),
+ {ok, [{appender, Appender, Name}]}.
+
+handle_call({add_sup_handler, Logger, Conf}, _From, [{appender, Appender, Name}] = State) ->
+ ?LOG2("Adding handler ~p with name ~p for ~p From ~p~n",[Appender, Name, Logger, _From]),
+ gen_event:add_sup_handler(Logger, {Appender, Name}, Conf),
+ {reply, ok, State};
+handle_call(_Msg, _From, State) ->
+ {reply, ok, State}.
+
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+handle_info({gen_event_EXIT, _Mod, R}, State)