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