ab9bd24f0950c346704dad1923ba6bb1b1172d31
[folly.git] / folly / experimental / logging / Logger.h
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 #pragma once
17
18 #include <folly/Conv.h>
19 #include <folly/Format.h>
20 #include <folly/experimental/logging/LogCategory.h>
21 #include <folly/experimental/logging/LogLevel.h>
22 #include <folly/experimental/logging/LogStream.h>
23 #include <folly/experimental/logging/LogStreamProcessor.h>
24
25 /**
26  * Helper macro for implementing FB_LOG() and FB_LOGF().
27  *
28  * This macro generally should not be used directly by end users.
29  */
30 #define FB_LOG_IMPL(logger, level, type, ...)               \
31   (!(logger).getCategory()->logCheck(level))                \
32       ? (void)0                                             \
33       : ::folly::LogStreamProcessor{(logger).getCategory(), \
34                                     (level),                \
35                                     __FILE__,               \
36                                     __LINE__,               \
37                                     (type),                 \
38                                     ##__VA_ARGS__} &        \
39           ::folly::LogStream()
40
41 /**
42  * Log a message to the specified logger.
43  *
44  * This macro avoids evaluating the log arguments unless the log level check
45  * succeeds.
46  *
47  * Beware that the logger argument is evaluated twice, so this argument should
48  * be an expression with no side-effects.
49  */
50 #define FB_LOG(logger, level, ...)         \
51   FB_LOG_IMPL(                             \
52       logger,                              \
53       ::folly::LogLevel::level,            \
54       ::folly::LogStreamProcessor::APPEND, \
55       ##__VA_ARGS__)
56
57 /**
58  * Log a message to the specified logger, using a folly::format() string.
59  *
60  * The arguments will be processed using folly::format().  The format syntax
61  * is similar to Python format strings.
62  *
63  * This macro avoids evaluating the log arguments unless the log level check
64  * succeeds.
65  *
66  * Beware that the logger argument is evaluated twice, so this argument should
67  * be an expression with no side-effects.
68  */
69 #define FB_LOGF(logger, level, fmt, arg1, ...) \
70   FB_LOG_IMPL(                                 \
71       logger,                                  \
72       ::folly::LogLevel::level,                \
73       ::folly::LogStreamProcessor::FORMAT,     \
74       fmt,                                     \
75       arg1,                                    \
76       ##__VA_ARGS__)
77
78 namespace folly {
79
80 class LoggerDB;
81 class LogMessage;
82
83 /**
84  * Logger is the class you will normally use to log messages.
85  *
86  * The Logger is really just a small wrapper class that contains a pointer
87  * to the appropriate LogCategory object.  It exists to allow for easy static
88  * initialization of log categories, as well as to provide fast checking of the
89  * current effective log level.
90  */
91 class Logger {
92  public:
93   /**
94    * Construct a Logger for the given category name.
95    *
96    * A LogCategory object for this category will be created if one does not
97    * already exist.
98    */
99   explicit Logger(folly::StringPiece name);
100
101   /**
102    * Construct a Logger pointing to an existing LogCategory object.
103    */
104   explicit Logger(LogCategory* cat);
105
106   /**
107    * Construct a Logger for a specific LoggerDB object, rather than the main
108    * singleton.
109    *
110    * This is primarily intended for use in unit tests.
111    */
112   Logger(LoggerDB* db, folly::StringPiece name);
113
114   /**
115    * Get the LogCategory that this Logger refers to.
116    */
117   LogCategory* getCategory() const {
118     return category_;
119   }
120
121  private:
122   LogCategory* const category_{nullptr};
123 };
124 }