1// Copyright (c) 2014 - Cloud Instruments Co., Ltd.
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this
9//    list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11//    this list of conditions and the following disclaimer in the documentation
12//    and/or other materials provided with the distribution.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25/*
26Package seelog implements logging functionality with flexible dispatching, filtering, and formatting.
27
28Creation
29
30To create a logger, use one of the following constructors:
31  func LoggerFromConfigAsBytes
32  func LoggerFromConfigAsFile
33  func LoggerFromConfigAsString
34  func LoggerFromWriterWithMinLevel
35  func LoggerFromWriterWithMinLevelAndFormat
36  func LoggerFromCustomReceiver (check https://github.com/cihub/seelog/wiki/Custom-receivers)
37Example:
38  import log "github.com/cihub/seelog"
39
40  func main() {
41      logger, err := log.LoggerFromConfigAsFile("seelog.xml")
42      if err != nil {
43          panic(err)
44      }
45      defer logger.Flush()
46      ... use logger ...
47  }
48The "defer" line is important because if you are using asynchronous logger behavior, without this line you may end up losing some
49messages when you close your application because they are processed in another non-blocking goroutine. To avoid that you
50explicitly defer flushing all messages before closing.
51
52Usage
53
54Logger created using one of the LoggerFrom* funcs can be used directly by calling one of the main log funcs.
55Example:
56  import log "github.com/cihub/seelog"
57
58  func main() {
59      logger, err := log.LoggerFromConfigAsFile("seelog.xml")
60      if err != nil {
61          panic(err)
62      }
63      defer logger.Flush()
64      logger.Trace("test")
65      logger.Debugf("var = %s", "abc")
66  }
67
68Having loggers as variables is convenient if you are writing your own package with internal logging or if you have
69several loggers with different options.
70But for most standalone apps it is more convenient to use package level funcs and vars. There is a package level
71var 'Current' made for it. You can replace it with another logger using 'ReplaceLogger' and then use package level funcs:
72  import log "github.com/cihub/seelog"
73
74  func main() {
75      logger, err := log.LoggerFromConfigAsFile("seelog.xml")
76      if err != nil {
77          panic(err)
78      }
79      log.ReplaceLogger(logger)
80      defer log.Flush()
81      log.Trace("test")
82      log.Debugf("var = %s", "abc")
83  }
84Last lines
85      log.Trace("test")
86      log.Debugf("var = %s", "abc")
87do the same as
88      log.Current.Trace("test")
89      log.Current.Debugf("var = %s", "abc")
90In this example the 'Current' logger was replaced using a 'ReplaceLogger' call and became equal to 'logger' variable created from config.
91This way you are able to use package level funcs instead of passing the logger variable.
92
93Configuration
94
95Main seelog point is to configure logger via config files and not the code.
96The configuration is read by LoggerFrom* funcs. These funcs read xml configuration from different sources and try
97to create a logger using it.
98
99All the configuration features are covered in detail in the official wiki: https://github.com/cihub/seelog/wiki.
100There are many sections covering different aspects of seelog, but the most important for understanding configs are:
101    https://github.com/cihub/seelog/wiki/Constraints-and-exceptions
102    https://github.com/cihub/seelog/wiki/Dispatchers-and-receivers
103    https://github.com/cihub/seelog/wiki/Formatting
104    https://github.com/cihub/seelog/wiki/Logger-types
105After you understand these concepts, check the 'Reference' section on the main wiki page to get the up-to-date
106list of dispatchers, receivers, formats, and logger types.
107
108Here is an example config with all these features:
109    <seelog type="adaptive" mininterval="2000000" maxinterval="100000000" critmsgcount="500" minlevel="debug">
110        <exceptions>
111            <exception filepattern="test*" minlevel="error"/>
112        </exceptions>
113        <outputs formatid="all">
114            <file path="all.log"/>
115            <filter levels="info">
116              <console formatid="fmtinfo"/>
117            </filter>
118            <filter levels="error,critical" formatid="fmterror">
119              <console/>
120              <file path="errors.log"/>
121            </filter>
122        </outputs>
123        <formats>
124            <format id="fmtinfo" format="[%Level] [%Time] %Msg%n"/>
125            <format id="fmterror" format="[%LEVEL] [%Time] [%FuncShort @ %File.%Line] %Msg%n"/>
126            <format id="all" format="[%Level] [%Time] [@ %File.%Line] %Msg%n"/>
127            <format id="criticalemail" format="Critical error on our server!\n    %Time %Date %RelFile %Func %Msg \nSent by Seelog"/>
128        </formats>
129    </seelog>
130This config represents a logger with adaptive timeout between log messages (check logger types reference) which
131logs to console, all.log, and errors.log depending on the log level. Its output formats also depend on log level. This logger will only
132use log level 'debug' and higher (minlevel is set) for all files with names that don't start with 'test'. For files starting with 'test'
133this logger prohibits all levels below 'error'.
134
135Configuration using code
136
137Although configuration using code is not recommended, it is sometimes needed and it is possible to do with seelog. Basically, what
138you need to do to get started is to create constraints, exceptions and a dispatcher tree (same as with config). Most of the New*
139functions in this package are used to provide such capabilities.
140
141Here is an example of configuration in code, that demonstrates an async loop logger that logs to a simple split dispatcher with
142a console receiver using a specified format and is filtered using a top-level min-max constraints and one expection for
143the 'main.go' file. So, this is basically a demonstration of configuration of most of the features:
144
145  package main
146
147  import log "github.com/cihub/seelog"
148
149  func main() {
150      defer log.Flush()
151      log.Info("Hello from Seelog!")
152
153      consoleWriter, _ := log.NewConsoleWriter()
154      formatter, _ := log.NewFormatter("%Level %Msg %File%n")
155      root, _ := log.NewSplitDispatcher(formatter, []interface{}{consoleWriter})
156      constraints, _ := log.NewMinMaxConstraints(log.TraceLvl, log.CriticalLvl)
157      specificConstraints, _ := log.NewListConstraints([]log.LogLevel{log.InfoLvl, log.ErrorLvl})
158      ex, _ := log.NewLogLevelException("*", "*main.go", specificConstraints)
159      exceptions := []*log.LogLevelException{ex}
160
161      logger := log.NewAsyncLoopLogger(log.NewLoggerConfig(constraints, exceptions, root))
162      log.ReplaceLogger(logger)
163
164      log.Trace("This should not be seen")
165      log.Debug("This should not be seen")
166      log.Info("Test")
167      log.Error("Test2")
168  }
169
170Examples
171
172To learn seelog features faster you should check the examples package: https://github.com/cihub/seelog-examples
173It contains many example configs and usecases.
174*/
175package seelog
176