 |
Changeset 3485
- Timestamp:
- 05/04/08 19:30:14
(7 months ago)
- Author:
- kris
- Message:
Reworked the log package to be cleaner, tighter, leaner, and more usable
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r2467 |
r3485 |
|
| 1 | 1 | private import tango.core.Thread; |
|---|
| 2 | 2 | |
|---|
| 3 | | private import tango.util.log.Configurator; |
|---|
| | 3 | private import tango.util.log.Log, |
|---|
| | 4 | tango.util.log.Config; |
|---|
| 4 | 5 | |
|---|
| 5 | 6 | private import tango.net.cluster.NetworkAlert; |
|---|
| r2978 |
r3485 |
|
| 6 | 6 | import tango.io.Stdout; |
|---|
| 7 | 7 | |
|---|
| | 8 | import tango.util.log.Log, |
|---|
| | 9 | tango.util.log.Config; |
|---|
| | 10 | |
|---|
| 8 | 11 | import tango.time.StopWatch; |
|---|
| 9 | | |
|---|
| 10 | | import tango.util.log.Configurator; |
|---|
| 11 | 12 | |
|---|
| 12 | 13 | import tango.net.cluster.NetworkCache; |
|---|
| … | … | |
| 22 | 23 | { |
|---|
| 23 | 24 | StopWatch w; |
|---|
| 24 | | |
|---|
| | 25 | |
|---|
| 25 | 26 | if (args.length > 1) |
|---|
| 26 | 27 | { |
|---|
| r2467 |
r3485 |
|
| 1 | 1 | private import tango.core.Thread; |
|---|
| 2 | 2 | |
|---|
| 3 | | private import tango.util.log.Configurator; |
|---|
| | 3 | private import tango.util.log.Log, |
|---|
| | 4 | tango.util.log.Config; |
|---|
| 4 | 5 | |
|---|
| 5 | 6 | private import tango.net.cluster.tina.Cluster; |
|---|
| r2978 |
r3485 |
|
| 6 | 6 | import tango.io.Stdout; |
|---|
| 7 | 7 | |
|---|
| | 8 | import tango.util.log.Log, |
|---|
| | 9 | tango.util.log.Config; |
|---|
| | 10 | |
|---|
| 8 | 11 | import tango.time.StopWatch; |
|---|
| 9 | | |
|---|
| 10 | | import tango.util.log.Configurator; |
|---|
| 11 | 12 | |
|---|
| 12 | 13 | import tango.net.cluster.NetworkQueue; |
|---|
| r2467 |
r3485 |
|
| 1 | 1 | private import tango.core.Thread; |
|---|
| 2 | 2 | |
|---|
| 3 | | private import tango.util.log.Configurator; |
|---|
| | 3 | private import tango.util.log.Log, |
|---|
| | 4 | tango.util.log.Config; |
|---|
| 4 | 5 | |
|---|
| 5 | 6 | private import tango.net.cluster.NetworkQueue; |
|---|
| … | … | |
| 20 | 21 | event.log.info ("received asynch msg on channel " ~ event.channel.name); |
|---|
| 21 | 22 | } |
|---|
| 22 | | |
|---|
| 23 | 23 | |
|---|
| 24 | 24 | // join the cluster |
|---|
| r2468 |
r3485 |
|
| 1 | | private import tango.util.log.Configurator; |
|---|
| | 1 | private import tango.util.log.Log, |
|---|
| | 2 | tango.util.log.Config; |
|---|
| 2 | 3 | |
|---|
| 3 | 4 | private import tango.net.cluster.NetworkQueue; |
|---|
| r2467 |
r3485 |
|
| 1 | 1 | private import tango.core.Thread; |
|---|
| 2 | 2 | |
|---|
| 3 | | private import tango.util.log.Configurator; |
|---|
| | 3 | private import tango.util.log.Log, |
|---|
| | 4 | tango.util.log.Config; |
|---|
| 4 | 5 | |
|---|
| 5 | 6 | private import tango.net.cluster.tina.Cluster; |
|---|
| r2978 |
r3485 |
|
| 8 | 8 | import tango.io.Stdout; |
|---|
| 9 | 9 | |
|---|
| | 10 | import tango.util.log.Log, |
|---|
| | 11 | tango.util.log.Config; |
|---|
| | 12 | |
|---|
| 10 | 13 | import tango.time.StopWatch; |
|---|
| 11 | | |
|---|
| 12 | | import tango.util.log.Configurator; |
|---|
| 13 | 14 | |
|---|
| 14 | 15 | import tango.net.cluster.tina.ClusterTask; |
|---|
| r2465 |
r3485 |
|
| 2 | 2 | |
|---|
| 3 | 3 | import tango.util.log.Log, |
|---|
| 4 | | tango.util.log.Log4Layout, |
|---|
| 5 | | tango.util.log.SocketAppender; |
|---|
| | 4 | tango.util.log.AppendSocket, |
|---|
| | 5 | tango.util.log.LayoutChainsaw; |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | import tango.net.InternetAddress; |
|---|
| … | … | |
| 18 | 18 | { |
|---|
| 19 | 19 | // get a logger to represent this module |
|---|
| 20 | | auto logger = Log.getLogger ("example.chainsaw"); |
|---|
| | 20 | auto logger = Log.lookup ("example.chainsaw"); |
|---|
| 21 | 21 | |
|---|
| 22 | 22 | // hook up an appender for XML output |
|---|
| 23 | | logger.addAppender (new SocketAppender (new InternetAddress("127.0.0.1", 4448), new Log4Layout)); |
|---|
| | 23 | logger.add (new AppendSocket (new InternetAddress("127.0.0.1", 4448), new LayoutChainsaw)); |
|---|
| 24 | 24 | |
|---|
| 25 | 25 | while (true) |
|---|
| r2913 |
r3485 |
|
| 5 | 5 | *******************************************************************************/ |
|---|
| 6 | 6 | |
|---|
| 7 | | private import tango.util.log.Log, |
|---|
| 8 | | tango.util.log.Configurator; |
|---|
| | 7 | import tango.util.log.Log, |
|---|
| | 8 | tango.util.log.Config; |
|---|
| 9 | 9 | |
|---|
| 10 | 10 | /******************************************************************************* |
|---|
| … | … | |
| 15 | 15 | |
|---|
| 16 | 16 | void compute (Logger log, uint max) |
|---|
| 17 | | { |
|---|
| | 17 | { |
|---|
| 18 | 18 | byte* feld; |
|---|
| 19 | 19 | int teste=1, |
|---|
| … | … | |
| 23 | 23 | e = 1; |
|---|
| 24 | 24 | int count; |
|---|
| 25 | | char tmp[128] = void; |
|---|
| 26 | 25 | |
|---|
| 27 | 26 | void set (byte* f, uint x) |
|---|
| … | … | |
| 35 | 34 | } |
|---|
| 36 | 35 | |
|---|
| | 36 | // get a log formatting instance |
|---|
| | 37 | auto format = Log.format; |
|---|
| | 38 | |
|---|
| 37 | 39 | // information level |
|---|
| 38 | | log.info (log.format (tmp, "Searching prime numbers up to {}", max)); |
|---|
| | 40 | log.info (format ("Searching prime numbers up to {}", max)); |
|---|
| 39 | 41 | |
|---|
| 40 | 42 | feld = (new byte[max / 16 + 1]).ptr; |
|---|
| 41 | | |
|---|
| 42 | | // get milliseconds since application began |
|---|
| 43 | | auto begin = log.runtime; |
|---|
| 44 | 43 | |
|---|
| 45 | 44 | while ((teste += 2) < max) |
|---|
| … | … | |
| 48 | 47 | if ((++hits & 0x0f) == 0) |
|---|
| 49 | 48 | // more information level |
|---|
| 50 | | log.info (log.format (tmp, "found {}", hits)); |
|---|
| | 49 | log.info (format ("found {}", hits)); |
|---|
| 51 | 50 | |
|---|
| 52 | 51 | for (mom=3*teste; mom < max; mom += teste<<1) |
|---|
| … | … | |
| 54 | 53 | } |
|---|
| 55 | 54 | |
|---|
| 56 | | // get number of milliseconds we took to compute |
|---|
| 57 | | auto period = log.runtime - begin; |
|---|
| 58 | | |
|---|
| 59 | 55 | if (hits) |
|---|
| 60 | 56 | // more information |
|---|
| 61 | | log.info (log.format (tmp, "{} prime numbers found in {} millsecs", hits, period)); |
|---|
| | 57 | log.info (format ("{} prime numbers found", hits)); |
|---|
| 62 | 58 | else |
|---|
| 63 | 59 | // a warning level |
|---|
| … | … | |
| 66 | 62 | // check to see if we're enabled for |
|---|
| 67 | 63 | // tracing before we expend a lot of effort |
|---|
| 68 | | if (log.isEnabled (log.Level.Trace)) |
|---|
| | 64 | if (log.enabled (Level.Trace)) |
|---|
| 69 | 65 | { |
|---|
| 70 | 66 | e = max; |
|---|
| … | … | |
| 76 | 72 | // log trace information |
|---|
| 77 | 73 | if (! test (feld, count)) |
|---|
| 78 | | log.trace (log.format (tmp, "prime found: {}", count)); |
|---|
| | 74 | log.trace (format ("prime found: {}", count)); |
|---|
| 79 | 75 | } |
|---|
| 80 | 76 | } |
|---|
| … | … | |
| 89 | 85 | void main() |
|---|
| 90 | 86 | { |
|---|
| 91 | | // get a logger to represent this module. We could just as |
|---|
| 92 | | // easily share a name with some other module(s) |
|---|
| 93 | | auto log = Log.getLogger ("example.logging"); |
|---|
| | 87 | // get a logger to represent this module |
|---|
| | 88 | auto log = Log.lookup ("example.logging"); |
|---|
| 94 | 89 | try { |
|---|
| 95 | 90 | compute (log, 1000); |
|---|
| 96 | | |
|---|
| 97 | 91 | } catch (Exception x) |
|---|
| 98 | 92 | { |
|---|
| 99 | | // log the exception as an error |
|---|
| 100 | | log.error ("Exception: " ~ x.toString); |
|---|
| | 93 | // log the exception as a fatal error |
|---|
| | 94 | log.fatal ("Exception: " ~ x.toString); |
|---|
| 101 | 95 | } |
|---|
| 102 | 96 | } |
|---|
| r3083 |
r3485 |
|
| 1 | 1 | import tango.util.log.Log; |
|---|
| 2 | | import tango.util.log.Log4Layout; |
|---|
| 3 | | import tango.util.log.FileAppender; |
|---|
| 4 | | import tango.util.log.ConsoleAppender; |
|---|
| 5 | | import tango.util.log.RollingFileAppender; |
|---|
| | 2 | import tango.util.log.AppendFile; |
|---|
| | 3 | import tango.util.log.AppendFiles; |
|---|
| | 4 | import tango.util.log.AppendConsole; |
|---|
| | 5 | import tango.util.log.LayoutChainsaw; |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | /******************************************************************************* |
|---|
| … | … | |
| 14 | 14 | { |
|---|
| 15 | 15 | // set default logging level at the root |
|---|
| 16 | | auto log = Log.getRootLogger; |
|---|
| 17 | | log.setLevel (log.Level.Trace); |
|---|
| | 16 | auto log = Log.root; |
|---|
| | 17 | log.level = Level.Trace; |
|---|
| 18 | 18 | |
|---|
| 19 | 19 | // 10 logs, all with 10 mbs each |
|---|
| 20 | | log.addAppender (new RollingFileAppender("rolling.log", 9, 1024*1024*10)); |
|---|
| | 20 | log.add (new AppendFiles ("rolling.log", 9, 1024*1024*10)); |
|---|
| 21 | 21 | |
|---|
| 22 | 22 | // a single file appender, with an XML layout |
|---|
| 23 | | log.addAppender (new FileAppender ("single.log", new Log4Layout)); |
|---|
| | 23 | log.add (new AppendFile ("single.log", new LayoutChainsaw)); |
|---|
| 24 | 24 | |
|---|
| 25 | 25 | // console appender |
|---|
| 26 | | log.addAppender (new ConsoleAppender); |
|---|
| | 26 | log.add (new AppendConsole); |
|---|
| 27 | 27 | |
|---|
| 28 | 28 | // log to all |
|---|
| r2983 |
r3485 |
|
| 26 | 26 | import tango.net.ServerSocket; |
|---|
| 27 | 27 | import tango.time.Clock; |
|---|
| 28 | | import tango.util.log.Log; |
|---|
| 29 | | import tango.util.log.ConsoleAppender; |
|---|
| 30 | | import tango.util.log.DateLayout; |
|---|
| 31 | 28 | import tango.text.convert.Sprint; |
|---|
| 32 | 29 | import tango.core.Exception; |
|---|
| … | … | |
| 34 | 31 | import tango.sys.Common; |
|---|
| 35 | 32 | import tango.stdc.errno; |
|---|
| | 33 | import tango.util.log.Log; |
|---|
| | 34 | import tango.util.log.LayoutDate; |
|---|
| | 35 | import tango.util.log.AppendConsole; |
|---|
| 36 | 36 | } |
|---|
| 37 | 37 | |
|---|
| … | … | |
| 46 | 46 | int main(char[][] args) |
|---|
| 47 | 47 | { |
|---|
| 48 | | Logger log = Log.getLogger("selector"); |
|---|
| | 48 | Logger log = Log.lookup("selector"); |
|---|
| 49 | 49 | Sprint!(char) sprint = new Sprint!(char)(256); |
|---|
| 50 | 50 | |
|---|
| 51 | | log.addAppender(new ConsoleAppender(new DateLayout())); |
|---|
| | 51 | log.add (new AppendConsole(new LayoutDate)); |
|---|
| 52 | 52 | |
|---|
| 53 | 53 | ISelector selector; |
|---|
| r3324 |
r3485 |
|
| 12 | 12 | import tango.time.StopWatch; |
|---|
| 13 | 13 | import tango.text.xml.Document; |
|---|
| | 14 | import tango.text.xml.DocPrinter; |
|---|
| 14 | 15 | |
|---|
| 15 | 16 | /******************************************************************************* |
|---|
| … | … | |
| 22 | 23 | |
|---|
| 23 | 24 | auto doc = new Document!(char); |
|---|
| 24 | | auto content = cast (char[]) File("hamlet.xml").read; |
|---|
| | 25 | auto content = cast (char[]) File("test.xml").read; |
|---|
| 25 | 26 | |
|---|
| 26 | 27 | elapsed.start; |
|---|
| … | … | |
| 28 | 29 | doc.parse (content); |
|---|
| 29 | 30 | |
|---|
| 30 | | Stdout.formatln ("{} MB/s", (content.length * iterations) / (elapsed.stop * (1024 * 1024))); |
|---|
| | 31 | foreach (node; doc.query.descendant("xyz")) |
|---|
| | 32 | node.detach; |
|---|
| | 33 | |
|---|
| | 34 | auto print = new DocPrinter!(char); |
|---|
| | 35 | Stdout (print (doc)).newline; |
|---|
| | 36 | // Stdout.formatln ("{} MB/s", (content.length * iterations) / (elapsed.stop * (1024 * 1024))); |
|---|
| 31 | 37 | } |
|---|
| 32 | 38 | |
|---|
| … | … | |
| 37 | 43 | void main() |
|---|
| 38 | 44 | { |
|---|
| 39 | | for (int i=10; i--;) |
|---|
| | 45 | for (int i=1; i--;) |
|---|
| 40 | 46 | bench (2000); |
|---|
| 41 | 47 | } |
|---|
| r3410 |
r3485 |
|
| 18 | 18 | |
|---|
| 19 | 19 | public import tango.util.log.Log; |
|---|
| 20 | | public import tango.util.log.Logger; |
|---|
| 21 | | public import tango.util.log.Hierarchy; |
|---|
| 22 | | public import tango.util.log.DateLayout; |
|---|
| 23 | | public import tango.util.log.Log4Layout; |
|---|
| 24 | | public import tango.util.log.EventLayout; |
|---|
| 25 | | public import tango.util.log.FileAppender; |
|---|
| 26 | | public import tango.util.log.MailAppender; |
|---|
| 27 | | public import tango.util.log.SocketAppender; |
|---|
| 28 | | public import tango.util.log.ConsoleAppender; |
|---|
| 29 | | public import tango.util.log.RollingFileAppender; |
|---|
| | 20 | public import tango.util.log.LayoutDate; |
|---|
| | 21 | public import tango.util.log.LayoutChainsaw; |
|---|
| | 22 | public import tango.util.log.AppendFile; |
|---|
| | 23 | public import tango.util.log.AppendMail; |
|---|
| | 24 | public import tango.util.log.AppendSocket; |
|---|
| | 25 | public import tango.util.log.AppendFiles; |
|---|
| 30 | 26 | |
|---|
| 31 | 27 | |
|---|
| r3038 |
r3485 |
|
| 104 | 104 | ***********************************************************************/ |
|---|
| 105 | 105 | |
|---|
| 106 | | Logger log () |
|---|
| | 106 | ILogger log () |
|---|
| 107 | 107 | { |
|---|
| 108 | 108 | return cluster_.log; |
|---|
| r2809 |
r3485 |
|
| 13 | 13 | module tango.net.cluster.model.IChannel; |
|---|
| 14 | 14 | |
|---|
| 15 | | private import tango.util.log.Logger; |
|---|
| | 15 | private import tango.util.log.model.ILogger; |
|---|
| 16 | 16 | |
|---|
| 17 | 17 | private import tango.net.cluster.model.IMessage, |
|---|
| … | … | |
| 36 | 36 | ***********************************************************************/ |
|---|
| 37 | 37 | |
|---|
| 38 | | Logger log (); |
|---|
| | 38 | ILogger log (); |
|---|
| 39 | 39 | |
|---|
| 40 | 40 | /*********************************************************************** |
|---|
| … | … | |
| 190 | 190 | ***********************************************************************/ |
|---|
| 191 | 191 | |
|---|
| 192 | | Logger log (); |
|---|
| | 192 | ILogger log (); |
|---|
| 193 | 193 | } |
|---|
| 194 | 194 | |
|---|
| r2809 |
r3485 |
|
| 13 | 13 | module tango.net.cluster.model.ICluster; |
|---|
| 14 | 14 | |
|---|
| 15 | | public import tango.util.log.Logger; |
|---|
| | 15 | public import tango.util.log.model.ILogger; |
|---|
| 16 | 16 | |
|---|
| 17 | 17 | public import tango.net.cluster.model.IChannel, |
|---|
| … | … | |
| 45 | 45 | ***********************************************************************/ |
|---|
| 46 | 46 | |
|---|
| 47 | | Logger log (); |
|---|
| | 47 | ILogger log (); |
|---|
| 48 | 48 | } |
|---|
| r2983 |
r3485 |
|
| 19 | 19 | tango.core.Exception; |
|---|
| 20 | 20 | |
|---|
| 21 | | private import tango.util.log.Log, |
|---|
| 22 | | tango.util.log.Logger; |
|---|
| | 21 | private import tango.util.log.Log; |
|---|
| 23 | 22 | |
|---|
| 24 | 23 | private import tango.time.Clock; |
|---|
| r2932 |
r3485 |
|
| 27 | 27 | class ClusterQueue |
|---|
| 28 | 28 | { |
|---|
| 29 | | private Logger log; |
|---|
| | 29 | private ILogger log; |
|---|
| 30 | 30 | private uint used, |
|---|
| 31 | 31 | limit; |
|---|
| r3416 |
r3485 |
|
| 13 | 13 | module tango.net.cluster.tina.CmdParser; |
|---|
| 14 | 14 | |
|---|
| | 15 | private import tango.util.log.Log, |
|---|
| | 16 | tango.util.log.Config; |
|---|
| | 17 | |
|---|
| 15 | 18 | private import tango.util.Arguments; |
|---|
| 16 | 19 | |
|---|
| 17 | 20 | private import tango.text.convert.Integer; |
|---|
| 18 | | |
|---|
| 19 | | private import tango.util.log.Log, |
|---|
| 20 | | tango.util.log.Configurator; |
|---|
| 21 | 21 | |
|---|
| 22 | 22 | /****************************************************************************** |
|---|
| … | … | |
| 39 | 39 | this (char[] name) |
|---|
| 40 | 40 | { |
|---|
| 41 | | log = Log.getLogger (name); |
|---|
| | 41 | log = Log.lookup (name); |
|---|
| 42 | 42 | |
|---|
| 43 | 43 | // default logging is info, not trace |
|---|
| 44 | | log.setLevel (log.Level.Info); |
|---|
| | 44 | log.level = Level.Info; |
|---|
| 45 | 45 | } |
|---|
| 46 | 46 | |
|---|
| … | … | |
| 61 | 61 | help = true; |
|---|
| 62 | 62 | if (this.contains("log")) |
|---|
| 63 | | log.setLevel(Log.level(this["log"])); |
|---|
| | 63 | log.level = Log.convert(this["log"]); |
|---|
| 64 | 64 | if (this.contains("port")) |
|---|
| 65 | 65 | port = cast(ushort)atoi(this["port"]); |
|---|
| r2978 |
r3485 |
|
| 16 | 16 | tango.io.FileConduit; |
|---|
| 17 | 17 | |
|---|
| 18 | | private import tango.util.log.Logger; |
|---|
| | 18 | private import tango.util.log.model.ILogger; |
|---|
| 19 | 19 | |
|---|
| 20 | 20 | private import tango.text.convert.Sprint; |
|---|
| … | … | |
| 41 | 41 | } |
|---|
| 42 | 42 | |
|---|
| 43 | | private Logger log; // logging target |
|---|
| | 43 | private ILogger log; // logging target |
|---|
| 44 | 44 | private bool dirty; // is queue dirty? |
|---|
| 45 | 45 | private uint limit, // max file size |
|---|
| … | … | |
| 56 | 56 | **********************************************************************/ |
|---|
| 57 | 57 | |
|---|
| 58 | | this (Logger log, IChannel channel, uint max, uint min=1024*1024) |
|---|
| | 58 | this (ILogger log, IChannel channel, uint max, uint min=1024*1024) |
|---|
| 59 | 59 | { |
|---|
| 60 | 60 | this (log, channel.name~".queue", max, min); |
|---|
| … | … | |
| 66 | 66 | **********************************************************************/ |
|---|
| 67 | 67 | |
|---|
| 68 | | this (Logger log, char[] name, uint max, uint min=1024*1024) |
|---|
| | 68 | this (ILogger log, char[] name, uint max, uint min=1024*1024) |
|---|
| 69 | 69 | { |
|---|
| 70 | 70 | Header tmp; |
|---|
| r2809 |
r3485 |
|
| 11 | 11 | *******************************************************************************/ |
|---|
| 12 | 12 | |
|---|
| 13 | | module tango.util.log.Configurator; |
|---|
| | 13 | module tango.util.log.Config; |
|---|
| 14 | 14 | |
|---|
| 15 | 15 | private import tango.util.log.Log, |
|---|
| 16 | | tango.util.log.EventLayout, |
|---|
| 17 | | tango.util.log.ConsoleAppender; |
|---|
| | 16 | tango.util.log.AppendConsole; |
|---|
| 18 | 17 | |
|---|
| 19 | 18 | /******************************************************************************* |
|---|
| 20 | 19 | |
|---|
| 21 | | Basic utility for initializing the basic behaviour of the |
|---|
| 22 | | default logging hierarchy. |
|---|
| | 20 | Utility for initializing the basic behaviour of the default |
|---|
| | 21 | logging hierarchy. |
|---|
| 23 | 22 | |
|---|
| 24 | | Adds a default StdioAppender, with a SimpleTimerLayout, to |
|---|
| 25 | | the root node, and set the activity level to be everything |
|---|
| 26 | | enabled. |
|---|
| | 23 | Adds a default console appender with a generic layout to the |
|---|
| | 24 | root node, and set the activity level to be everything enabled |
|---|
| 27 | 25 | |
|---|
| 28 | 26 | *******************************************************************************/ |
|---|
| 29 | 27 | |
|---|
| 30 | | static this() |
|---|
| | 28 | static this () |
|---|
| 31 | 29 | { |
|---|
| 32 | | Log.getRootLogger.addAppender(new ConsoleAppender(new SimpleTimerLayout)); |
|---|
| | 30 | Log.root.add (new AppendConsole (new LayoutTimer)); |
|---|
| 33 | 31 | } |
|---|
| 34 | | |
|---|
| 35 | | |
|---|
| 36 | | |
|---|
| 37 | | /******************************************************************************* |
|---|
| 38 | | |
|---|
| 39 | | *******************************************************************************/ |
|---|
| 40 | | |
|---|
| 41 | | public class Configurator |
|---|
| 42 | | { |
|---|
| 43 | | /*********************************************************************** |
|---|
| 44 | | |
|---|
| 45 | | No longer required. Just import this module instead |
|---|
| 46 | | |
|---|
| 47 | | ***********************************************************************/ |
|---|
| 48 | | |
|---|
| 49 | | deprecated static void opCall () |
|---|
| 50 | | { |
|---|
| 51 | | } |
|---|
| 52 | | } |
|---|
| 53 | | |
|---|
| r3029 |
r3485 |
|
| 10 | 10 | author: Kris |
|---|
| 11 | 11 | |
|---|
| | 12 | |
|---|
| | 13 | Loggers are named entities, sometimes shared, sometimes specific to |
|---|
| | 14 | a particular portion of code. The names are generally hierarchical in |
|---|
| | 15 | nature, using dot notation (with '.') to separate each named section. |
|---|
| | 16 | For example, a typical name might be something like "mail.send.writer" |
|---|
| | 17 | --- |
|---|
| | 18 | import tango.util.log.Log; |
|---|
| | 19 | |
|---|
| | 20 | auto log = Log.lookup ("mail.send.writer"); |
|---|
| | 21 | |
|---|
| | 22 | log.info ("an informational message"); |
|---|
| | 23 | log.error ("an exception message: " ~ exception.toString); |
|---|
| | 24 | |
|---|
| | 25 | etc ... |
|---|
| | 26 | --- |
|---|
| | 27 | |
|---|
| | 28 | It is considered good form to pass a logger instance as a function or |
|---|
| | 29 | class-ctor argument, or to assign a new logger instance during static |
|---|
| | 30 | class construction. For example: if it were considered appropriate to |
|---|
| | 31 | have one logger instance per class, each might be constructed like so: |
|---|
| | 32 | --- |
|---|
| | 33 | private Logger log; |
|---|
| | 34 | |
|---|
| | 35 | static this() |
|---|
| | 36 | { |
|---|
| | 37 | log = Log.lookup (nameOfThisClassOrStructOrModule); |
|---|
| | 38 | } |
|---|
| | 39 | --- |
|---|
| | 40 | |
|---|
| | 41 | Messages passed to a Logger are assumed to be pre-formatted. You |
|---|
| | 42 | may find that the format() methos is handy for collating various |
|---|
| | 43 | components of the message: |
|---|
| | 44 | --- |
|---|
| | 45 | auto format = Log.format; |
|---|
| | 46 | ... |
|---|
| | 47 | log.warn (format ("temperature is {} degrees!", 101)); |
|---|
| | 48 | --- |
|---|
| | 49 | |
|---|
| | 50 | Note that a provided workspace is used to format the message, which |
|---|
| | 51 | should generally be located on the stack so as to support multiple |
|---|
| | 52 | threads of execution. In the example above we indicate assignment as |
|---|
| | 53 | "tmp = void", although this is an optional attribute (see the language |
|---|
| | 54 | manual for more information). |
|---|
| | 55 | |
|---|
| | 56 | To avoid overhead when constructing formatted messages, the logging |
|---|
| | 57 | system employs lazy expressions such that the message is not constructed |
|---|
| | 58 | unless the logger is actually active. You can also explicitly check to |
|---|
| | 59 | see whether a logger is active or not: |
|---|
| | 60 | --- |
|---|
| | 61 | if (log.isEnabled (log.Level.Warn)) |
|---|
| | 62 | log.warn (format ("temperature is {} degrees!", 101)); |
|---|
| | 63 | --- |
|---|
| | 64 | |
|---|
| | 65 | You might optionally configure various layout & appender implementations |
|---|
| | 66 | to support specific rendering needs. |
|---|
| | 67 | |
|---|
| | 68 | tango.log closely follows both the API and the behaviour as documented |
|---|
| | 69 | at the official Log4J site, where you'll find a good tutorial. Those |
|---|
| | 70 | pages are hosted over |
|---|
| | 71 | <A HREF="http://logging.apache.org/log4j/docs/documentation.html">here</A>. |
|---|
| | 72 | |
|---|
| 12 | 73 | *******************************************************************************/ |
|---|
| 13 | 74 | |
|---|
| 14 | 75 | module tango.util.log.Log; |
|---|
| 15 | 76 | |
|---|
| 16 | | public import tango.util.log.Logger; |
|---|
| 17 | | |
|---|
| 18 | | private import tango.util.log.Event, |
|---|
| 19 | | tango.util.log.Hierarchy; |
|---|
| 20 | | |
|---|
| 21 | | private import tango.util.log.model.ILevel; |
|---|
| | 77 | private import tango.sys.Common; |
|---|
| | 78 | |
|---|
| | 79 | private import tango.time.Clock; |
|---|
| | 80 | |
|---|
| | 81 | private import tango.core.Exception; |
|---|
| | 82 | |
|---|
| | 83 | private import tango.io.model.IConduit; |
|---|
| | 84 | |
|---|
| | 85 | private import tango.text.convert.Format; |
|---|
| | 86 | |
|---|
| | 87 | private import tango.util.log.model.ILogger; |
|---|
| | 88 | |
|---|
| | 89 | /******************************************************************************* |
|---|
| | 90 | |
|---|
| | 91 | Pull in additional functions from the C library |
|---|
| | 92 | |
|---|
| | 93 | *******************************************************************************/ |
|---|
| | 94 | |
|---|
| | 95 | extern (C) |
|---|
| | 96 | { |
|---|
| | 97 | private int memcmp (void *, void *, int); |
|---|
| | 98 | } |
|---|
| | 99 | |
|---|
| | 100 | version (Win32) |
|---|
| | 101 | { |
|---|
| | 102 | private extern(Windows) int QueryPerformanceCounter(ulong *count); |
|---|
| | 103 | private extern(Windows) int QueryPerformanceFrequency(ulong *frequency); |
|---|
| | 104 | } |
|---|
| | 105 | |
|---|
| | 106 | /******************************************************************************* |
|---|
| | 107 | |
|---|
| | 108 | These represent the standard LOG4J event levels. Note that |
|---|
| | 109 | Debug is called Trace here, because debug is a reserved word |
|---|
| | 110 | in D |
|---|
| | 111 | |
|---|
| | 112 | *******************************************************************************/ |
|---|
| | 113 | |
|---|
| | 114 | alias ILogger.Level Level; |
|---|
| | 115 | |
|---|
| 22 | 116 | |
|---|
| 23 | 117 | /******************************************************************************* |
|---|
| … | … | |
| 30 | 124 | *******************************************************************************/ |
|---|
| 31 | 125 | |
|---|
| 32 | | class Log : ILevel |
|---|
| | 126 | public struct Log |
|---|
| 33 | 127 | { |
|---|
| 34 | | static private Hierarchy base; |
|---|
| 35 | | |
|---|
| 36 | | private static ILevel.Level[char[]] map; |
|---|
| 37 | | |
|---|
| 38 | | private struct Pair {char[] name; ILevel.Level value;} |
|---|
| 39 | | |
|---|
| | 128 | // support for old API |
|---|
| | 129 | public alias lookup getLogger; |
|---|
| | 130 | |
|---|
| | 131 | // internal use only |
|---|
| | 132 | private static Hierarchy base; |
|---|
| | 133 | private static Time beginTime; |
|---|
| | 134 | |
|---|
| | 135 | version (Win32) |
|---|
| | 136 | { |
|---|
| | 137 | private static double multiplier; |
|---|
| | 138 | private static ulong timerStart; |
|---|
| | 139 | } |
|---|
| | 140 | |
|---|
| | 141 | private struct Pair {char[] name; Level value;} |
|---|
| | 142 | |
|---|
| | 143 | private static Level [char[]] map; |
|---|
| | 144 | |
|---|
| 40 | 145 | private static Pair[] Pairs = |
|---|
| 41 | 146 | [ |
|---|
| 42 | | {"TRACE", ILevel.Level.Trace}, |
|---|
| 43 | | {"Trace", ILevel.Level.Trace}, |
|---|
| 44 | | {"trace", ILevel.Level.Trace}, |
|---|
| 45 | | {"INFO", ILevel.Level.Info}, |
|---|
| 46 | | {"Info", ILevel.Level.Info}, |
|---|
| 47 | | {"info", ILevel.Level.Info}, |
|---|
| 48 | | {"WARN", ILevel.Level.Warn}, |
|---|
| 49 | | {"Warn", ILevel.Level.Warn}, |
|---|
| 50 | | {"warn", ILevel.Level.Warn}, |
|---|
| 51 | | {"ERROR", ILevel.Level.Error}, |
|---|
| 52 | | {"Error", ILevel.Level.Error}, |
|---|
| 53 | | {"error", ILevel.Level.Error}, |
|---|
| 54 | | {"Fatal", ILevel.Level.Fatal}, |
|---|
| 55 | | {"FATAL", ILevel.Level.Fatal}, |
|---|
| 56 | | {"fatal", ILevel.Level.Fatal}, |
|---|
| 57 | | {"NONE", ILevel.Level.None}, |
|---|
| 58 | | {"None", ILevel.Level.None}, |
|---|
| 59 | | {"none", ILevel.Level.None}, |
|---|
| | 147 | {"TRACE", Level.Trace}, |
|---|
| | 148 | {"Trace", Level.Trace}, |
|---|
| | 149 | {"trace", Level.Trace}, |
|---|
| | 150 | {"INFO", Level.Info}, |
|---|
| | 151 | {"Info", Level.Info}, |
|---|
| | 152 | {"info", Level.Info}, |
|---|
| | 153 | {"WARN", Level.Warn}, |
|---|
| | 154 | {"Warn", Level.Warn}, |
|---|
| | 155 | {"warn", Level.Warn}, |
|---|
| | 156 | {"ERROR", Level.Error}, |
|---|
| | 157 | {"Error", Level.Error}, |
|---|
| | 158 | {"error", Level.Error}, |
|---|
| | 159 | {"Fatal", Level.Fatal}, |
|---|
| | 160 | {"FATAL", Level.Fatal}, |
|---|
| | 161 | {"fatal", Level.Fatal}, |
|---|
| | 162 | {"NONE", Level.None}, |
|---|
| | 163 | {"None", Level.None}, |
|---|
| | 164 | {"none", Level.None}, |
|---|
| 60 | 165 | ]; |
|---|
| 61 | 166 | |
|---|
| 62 | | /*********************************************************************** |
|---|
| 63 | | |
|---|
| 64 | | This is a singleton, so hide the constructor. |
|---|
| 65 | | |
|---|
| 66 | | ***********************************************************************/ |
|---|
| 67 | | |
|---|
| 68 | | private this () |
|---|
| 69 | | { |
|---|
| 70 | | } |
|---|
| 71 | | |
|---|
| 72 | | /*********************************************************************** |
|---|
| 73 | | |
|---|
| 74 | | Initialize the base hierarchy. |
|---|
| | 167 | // logging-level names |
|---|
| | 168 | private static char[][] LevelNames = |
|---|
| | 169 | [ |
|---|
| | 170 | "Trace ", "Info ", "Warn ", "Error ", "Fatal ", "None " |
|---|
| | 171 | ]; |
|---|
| | 172 | |
|---|
| | 173 | /*********************************************************************** |
|---|
| | 174 | |
|---|
| | 175 | Initialize the base hierarchy |
|---|
| 75 | 176 | |
|---|
| 76 | 177 | ***********************************************************************/ |
|---|
| … | … | |
| 79 | 180 | { |
|---|
| 80 | 181 | base = new Hierarchy ("tango"); |
|---|
| 81 | | Event.initialize (); |
|---|
| 82 | | |
|---|
| 83 | | // populate a map of acceptable level names |
|---|
| | 182 | |
|---|
| 84 | 183 | foreach (p; Pairs) |
|---|
| 85 | 184 | map[p.name] = p.value; |
|---|
| | 185 | |
|---|
| | 186 | version (Posix) |
|---|
| | 187 | { |
|---|
| | 188 | beginTime = Clock.now; |
|---|
| | 189 | } |
|---|
| | 190 | |
|---|
| | 191 | version (Win32) |
|---|
| | 192 | { |
|---|
| | 193 | ulong freq; |
|---|
| | 194 | |
|---|
| | 195 | if (! QueryPerformanceFrequency (&freq)) |
|---|
| | 196 | throw new PlatformException ("high-resolution timer is not available"); |
|---|
| | 197 | |
|---|
| | 198 | QueryPerformanceCounter (&timerStart); |
|---|
| | 199 | multiplier = cast(double) TimeSpan.TicksPerSecond / freq; |
|---|
| | 200 | beginTime = Clock.now; |
|---|
| | 201 | } |
|---|
| | 202 | } |
|---|
| | 203 | |
|---|
| | 204 | /*********************************************************************** |
|---|
| | 205 | |
|---|
| | 206 | Return the level of a given name |
|---|
| | 207 | |
|---|
| | 208 | ***********************************************************************/ |
|---|
| | 209 | |
|---|
| | 210 | static Level convert (char[] name, Level def=Level.Trace) |
|---|
| | 211 | { |
|---|
| | 212 | auto p = name in map; |
|---|
| | 213 | if (p) |
|---|
| | 214 | return *p; |
|---|
| | 215 | return def; |
|---|
| | 216 | } |
|---|
| | 217 | |
|---|
| | 218 | /*********************************************************************** |
|---|
| | 219 | |
|---|
| | 220 | Return the current time |
|---|
| | 221 | |
|---|
| | 222 | ************************ |
|---|
|