docs: provide custom sinks example (#1103)
This commit is contained in:
parent
0bad9688a0
commit
df683bbc81
@ -32,6 +32,7 @@ include (GetCacheVariables)
|
|||||||
include (GNUInstallDirs)
|
include (GNUInstallDirs)
|
||||||
|
|
||||||
option (BUILD_SHARED_LIBS "Build shared libraries" ON)
|
option (BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||||
|
option (BUILD_EXAMPLES "Build examples" ON)
|
||||||
option (PRINT_UNSYMBOLIZED_STACK_TRACES
|
option (PRINT_UNSYMBOLIZED_STACK_TRACES
|
||||||
"Print file offsets in traces instead of symbolizing" OFF)
|
"Print file offsets in traces instead of symbolizing" OFF)
|
||||||
option (WITH_GFLAGS "Use gflags" ON)
|
option (WITH_GFLAGS "Use gflags" ON)
|
||||||
@ -960,6 +961,11 @@ if (BUILD_TESTING)
|
|||||||
)
|
)
|
||||||
endif (BUILD_TESTING)
|
endif (BUILD_TESTING)
|
||||||
|
|
||||||
|
if (BUILD_EXAMPLES)
|
||||||
|
add_executable (custom_sink_example examples/custom_sink.cc)
|
||||||
|
target_link_libraries (custom_sink_example PRIVATE glog::glog)
|
||||||
|
endif (BUILD_EXAMPLES)
|
||||||
|
|
||||||
install (TARGETS glog
|
install (TARGETS glog
|
||||||
EXPORT glog-targets
|
EXPORT glog-targets
|
||||||
RUNTIME DESTINATION ${_glog_CMake_BINDIR}
|
RUNTIME DESTINATION ${_glog_CMake_BINDIR}
|
||||||
|
|||||||
84
docs/sinks.md
Normal file
84
docs/sinks.md
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Custom Sinks
|
||||||
|
|
||||||
|
Under certain circumstances, it is useful to send the log output to a
|
||||||
|
destination other than a file, `stderr` and/or `stdout`. In case, the library
|
||||||
|
provides the `#!cpp google::LogSink` interface whose implementations can be used
|
||||||
|
to write the log output to arbitrary locations.
|
||||||
|
|
||||||
|
## Basic Interface
|
||||||
|
|
||||||
|
The sink interface is defined as follows:
|
||||||
|
|
||||||
|
``` cpp
|
||||||
|
class LogSink {
|
||||||
|
public:
|
||||||
|
virtual void send(LogSeverity severity, const char* full_filename,
|
||||||
|
const char* base_filename, int line,
|
||||||
|
const LogMessageTime& time, const char* message,
|
||||||
|
size_t message_len);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The user must implement `#!cpp google::LogSink::send`, which is called by the
|
||||||
|
library every time a message is logged.
|
||||||
|
|
||||||
|
!!! warning "Possible deadlock due to nested logging"
|
||||||
|
This method can't use `LOG()` or `CHECK()` as logging system mutex(s) are
|
||||||
|
held during this call.
|
||||||
|
|
||||||
|
## Registering Log Sinks
|
||||||
|
|
||||||
|
To use the custom sink and instance of the above interface implementation must
|
||||||
|
be registered using `google::AddLogSink` which expects a pointer to the
|
||||||
|
`google::LogSink` instance. To unregister use `google::RemoveLogSink`. Both
|
||||||
|
functions are thread-safe.
|
||||||
|
|
||||||
|
!!! danger "`LogSink` ownership"
|
||||||
|
The `google::LogSink` instance must not be destroyed until the referencing
|
||||||
|
pointer is unregistered.
|
||||||
|
|
||||||
|
## Direct Logging
|
||||||
|
|
||||||
|
Instead of registering the sink, we can directly use to log messages. While `#!
|
||||||
|
LOG_TO_SINK(sink, severity)` allows to log both to the sink and to a global log
|
||||||
|
registry, e.g., a file, `#!cpp LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity)`
|
||||||
|
will avoid the latter.
|
||||||
|
|
||||||
|
!!! example "Using a custom sink"
|
||||||
|
``` cpp title="custom_sink.cc"
|
||||||
|
-8<- "examples/custom_sink.cc:33:"
|
||||||
|
```
|
||||||
|
|
||||||
|
1. `MySink` implements a custom sink that sends log messages to `std::cout`.
|
||||||
|
2. The custom sink must be registered to for use with existing logging
|
||||||
|
macros.
|
||||||
|
3. Once the custom sink is no longer needed we remove it from the registry.
|
||||||
|
4. A sink does not need to be registered globally. However, then, messages
|
||||||
|
must be logged using dedicated macros.
|
||||||
|
|
||||||
|
Running the above example as `#!bash GLOG_log_dir=. ./custom_sink_example`
|
||||||
|
will produce
|
||||||
|
|
||||||
|
<div class="annotate" markdown>
|
||||||
|
|
||||||
|
``` title="Custom sink output"
|
||||||
|
INFO custom_sink.cc:63 logging to MySink
|
||||||
|
INFO custom_sink.cc:68 direct logging
|
||||||
|
INFO custom_sink.cc:69 direct logging but not to file (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
1. This line is not present in the log file because we used
|
||||||
|
`LOG_TO_SINK_BUT_NOT_TO_LOGFILE` to log the message.
|
||||||
|
|
||||||
|
and the corresponding log file will contain
|
||||||
|
|
||||||
|
``` title="Log file generated with the custom sink"
|
||||||
|
Log file created at: 2024/06/11 13:24:27
|
||||||
|
Running on machine: pc
|
||||||
|
Running duration (h:mm:ss): 0:00:00
|
||||||
|
Log line format: [IWEF]yyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
I20240611 13:24:27.476620 126237946035776 custom_sink.cc:63] logging to MySink
|
||||||
|
I20240611 13:24:27.476796 126237946035776 custom_sink.cc:68] direct logging
|
||||||
|
```
|
||||||
71
examples/custom_sink.cc
Normal file
71
examples/custom_sink.cc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright (c) 2024, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Author: Sergiu Deitsch
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct MyLogSink : google::LogSink { // (1)!
|
||||||
|
void send(google::LogSeverity severity, const char* /*full_filename*/,
|
||||||
|
const char* base_filename, int line,
|
||||||
|
const google::LogMessageTime& /*time*/, const char* message,
|
||||||
|
std::size_t message_len) override {
|
||||||
|
std::cout << google::GetLogSeverityName(severity) << ' ' << base_filename
|
||||||
|
<< ':' << line << ' ';
|
||||||
|
std::copy_n(message, message_len,
|
||||||
|
std::ostreambuf_iterator<char>{std::cout});
|
||||||
|
std::cout << '\n';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main(int /*argc*/, char** argv) {
|
||||||
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
|
||||||
|
MyLogSink sink;
|
||||||
|
google::AddLogSink(&sink); // (2)!
|
||||||
|
|
||||||
|
LOG(INFO) << "logging to MySink";
|
||||||
|
|
||||||
|
google::RemoveLogSink(&sink); // (3)!
|
||||||
|
|
||||||
|
// We can directly log to a sink without registering it
|
||||||
|
LOG_TO_SINK(&sink, INFO) << "direct logging"; // (4)!
|
||||||
|
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
|
||||||
|
<< "direct logging but not to file";
|
||||||
|
}
|
||||||
@ -7,7 +7,9 @@ edit_uri: edit/0.7.x/docs/
|
|||||||
copyright: Copyright © 2024 Google Inc. & contributors - <a href="#__consent">Change cookie settings</a>
|
copyright: Copyright © 2024 Google Inc. & contributors - <a href="#__consent">Change cookie settings</a>
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- admonition
|
- admonition
|
||||||
|
- attr_list
|
||||||
- def_list
|
- def_list
|
||||||
|
- md_in_html
|
||||||
- pymdownx.details
|
- pymdownx.details
|
||||||
- pymdownx.highlight:
|
- pymdownx.highlight:
|
||||||
anchor_linenums: true
|
anchor_linenums: true
|
||||||
@ -26,8 +28,9 @@ theme:
|
|||||||
name: material
|
name: material
|
||||||
custom_dir: docs/overrides
|
custom_dir: docs/overrides
|
||||||
icon:
|
icon:
|
||||||
repo: fontawesome/brands/git-alt
|
annotation: material/chevron-right-circle
|
||||||
edit: material/pencil
|
edit: material/pencil
|
||||||
|
repo: fontawesome/brands/git-alt
|
||||||
view: material/eye
|
view: material/eye
|
||||||
language: en
|
language: en
|
||||||
features:
|
features:
|
||||||
@ -107,6 +110,7 @@ nav:
|
|||||||
- Installation using Package Managers: packages.md
|
- Installation using Package Managers: packages.md
|
||||||
- User Guide:
|
- User Guide:
|
||||||
- Logging: logging.md
|
- Logging: logging.md
|
||||||
|
- Custom Sinks: sinks.md
|
||||||
- Failure Handler: failures.md
|
- Failure Handler: failures.md
|
||||||
- Log Removal: log_cleaner.md
|
- Log Removal: log_cleaner.md
|
||||||
- Stripping Log Messages: log_stripping.md
|
- Stripping Log Messages: log_stripping.md
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user