73542a8e0500c2c35cf6c78f911ea40c58d6aa0f
[folly.git] / folly / experimental / logging / Init.cpp
1 /*
2  * Copyright 2004-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <folly/experimental/logging/Init.h>
17
18 #include <folly/experimental/logging/LogConfig.h>
19 #include <folly/experimental/logging/LogConfigParser.h>
20 #include <folly/experimental/logging/LoggerDB.h>
21 #include <folly/experimental/logging/StreamHandlerFactory.h>
22
23 namespace folly {
24
25 /**
26  * The base logging settings to be applied in initLogging(),
27  * before any user-specified settings.
28  *
29  * This defines a log handler named "default" that writes to stderr,
30  * and configures the root log category to log to this handler and have a log
31  * level setting of WARN.
32  *
33  * Note that the default log handler uses async=false, so that log messages are
34  * written immediately to stderr from the thread that generated the log
35  * message.  This is often undesirable, as it can slow down normal processing
36  * waiting for logging I/O.  However, using async=true has some trade-offs of
37  * its own: it causes a new thread to be started, and not all message may get
38  * flushed to stderr if the program crashes.  For now, using async=false seems
39  * like the safer trade-off here, but many programs may wish to change this
40  * default.
41  *
42  * The user-specified config string may override any of these values.
43  * If the user-specified config string ends up not using the default log
44  * handler, the handler will be automatically forgotten by the LoggerDB code.
45  */
46 constexpr StringPiece kDefaultLoggingConfig =
47     ".=WARN:default; default=stream:stream=stderr,async=false";
48
49 void initLogging(StringPiece configString) {
50   // Register the StreamHandlerFactory
51   LoggerDB::get()->registerHandlerFactory(
52       std::make_unique<StreamHandlerFactory>());
53
54   // TODO: In the future it would be nice to build a better mechanism so that
55   // additional LogHandlerFactory objects could be automatically registered on
56   // startup if they are linked into our current executable.
57   //
58   // For now we register only the StreamHandlerFactory.  There is a
59   // FileHandlerFactory, but we do not register it by default: it allows
60   // appending to arbitrary files based on the config settings, and we do not
61   // want to allow this by default for security reasons.  (In the future
62   // maybe it would be worth enabling the FileHandlerFactory by default if we
63   // confirm that we are not a setuid or setgid binary.  i.e., if the real
64   // UID+GID is the same as the effective UID+GID.)
65
66   // Parse the default log level settings before processing the input config
67   // string.
68   auto config = parseLogConfig(kDefaultLoggingConfig);
69
70   // Then apply the configuration string
71   if (!configString.empty()) {
72     auto inputConfig = parseLogConfig(configString);
73     config.update(inputConfig);
74   }
75
76   // Now apply the configuration to the LoggerDB
77   LoggerDB::get()->updateConfig(config);
78 }
79
80 } // namespace folly