blob: b35c3654264ec0d594b565da626b7f47acf62424 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_SYSLOG_STRUCTURED_BACKEND_CPP_FUCHSIA_SYSLOG_H_
#define LIB_SYSLOG_STRUCTURED_BACKEND_CPP_FUCHSIA_SYSLOG_H_
#include <lib/stdcompat/optional.h>
#include <lib/stdcompat/string_view.h>
#include <lib/syslog/structured_backend/fuchsia_syslog.h>
#include <lib/zx/channel.h>
#include <lib/zx/socket.h>
#include <stdint.h>
namespace fuchsia_syslog {
// Opaque structure representing the backend encode state.
// This structure only has meaning to the backend and application code shouldn't
// touch these values.
// LogBuffers store the state of a log record that is in the process of being
// encoded.
// A LogBuffer is initialized by calling BeginRecord,
// and is written to the LogSink by calling FlushRecord.
// Calling BeginRecord on a LogBuffer will always initialize it to its
// clean state.
class LogBuffer final {
public:
// Initializes a LogBuffer
// buffer -- The buffer to initialize
// severity -- The severity of the log
// file_name -- The name of the file that generated the log message
// line -- The line number that caused this message to be generated
// message -- The message to output. OWNERSHIP: If severity is LOG_FATAL
// then the caller maintains ownership of the message buffer and MUST NOT
// mutate of free the string until FlushRecord is called or the buffer is reset/discarded
// with another call to BeginRecord.
// condition -- Does nothing. Exists solely for compatibility with legacy code.
// is_printf -- Whether or not this is a printf message. If true,
// the message should be interpreted as a C-style printf before being displayed to the
// user.
// socket -- The socket to write the message to.
// dropped_count -- Number of dropped messages
// pid -- The process ID that generated the message.
// tid -- The thread ID that generated the message.
void BeginRecord(FuchsiaLogSeverity severity, cpp17::optional<cpp17::string_view> file_name,
unsigned int line, cpp17::optional<cpp17::string_view> message,
cpp17::optional<cpp17::string_view> condition, bool is_printf,
zx::unowned_socket socket, uint32_t dropped_count, zx_koid_t pid,
zx_koid_t tid) {
syslog_begin_record(&data_, severity, StringViewToCStr(file_name), StringViewLength(file_name),
line, StringViewToCStr(message), StringViewLength(message),
StringViewToCStr(condition), StringViewLength(condition), is_printf,
socket->get(), dropped_count, pid, tid);
}
// Transitional BeginRecord method, which doesn't include condition.
// The other one will be deleted once everyone switches to this one.
void BeginRecord(FuchsiaLogSeverity severity, cpp17::optional<cpp17::string_view> file_name,
unsigned int line, cpp17::optional<cpp17::string_view> message, bool is_printf,
zx::unowned_socket socket, uint32_t dropped_count, zx_koid_t pid,
zx_koid_t tid) {
syslog_begin_record_transitional(&data_, severity, StringViewToCStr(file_name),
StringViewLength(file_name), line, StringViewToCStr(message),
StringViewLength(message), is_printf, socket->get(),
dropped_count, pid, tid);
}
// Writes a key/value pair to the buffer.
void WriteKeyValue(cpp17::string_view key, cpp17::string_view value) {
syslog_write_key_value_string(&data_, StringViewToCStr(key), StringViewLength(key),
StringViewToCStr(value), StringViewLength(value));
}
// Writes a key/value pair to the buffer.
void WriteKeyValue(cpp17::string_view key, int64_t value) {
syslog_write_key_value_int64(&data_, StringViewToCStr(key), StringViewLength(key), value);
}
// Writes a key/value pair to the buffer.
void WriteKeyValue(cpp17::string_view key, uint64_t value) {
syslog_write_key_value_uint64(&data_, StringViewToCStr(key), StringViewLength(key), value);
}
// Writes a key/value pair to the buffer.
void WriteKeyValue(cpp17::string_view key, double value) {
syslog_write_key_value_double(&data_, StringViewToCStr(key), StringViewLength(key), value);
}
// Writes a key/value pair to the buffer.
template <typename V, typename = std::enable_if_t<std::is_same<V, bool>{}>>
void WriteKeyValue(cpp17::string_view key, V value) {
syslog_write_key_value_bool(&data_, StringViewToCStr(key), StringViewLength(key), value);
}
// Writes the LogBuffer to the socket.
bool FlushRecord() { return syslog_flush_record(&data_); }
private:
static const char* StringViewToCStr(cpp17::optional<cpp17::string_view> view) {
if (!view.has_value()) {
return nullptr;
}
return view.value().data();
}
static size_t StringViewLength(cpp17::optional<cpp17::string_view> view) {
if (!view.has_value()) {
return 0;
}
return view.value().length();
}
fuchsia_syslog_log_buffer_t data_;
};
} // namespace fuchsia_syslog
#endif // LIB_SYSLOG_STRUCTURED_BACKEND_CPP_FUCHSIA_SYSLOG_H_