| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #pragma once
- #include <memory>
- #include <sstream>
- #include <string>
- #include <chrono>
- #include "logging/log_buffer.h"
- #include "rocksdb/env.h"
- namespace ROCKSDB_NAMESPACE {
- class JSONWriter {
- public:
- JSONWriter() : state_(kExpectKey), first_element_(true), in_array_(false) {
- stream_ << "{";
- }
- void AddKey(const std::string& key) {
- assert(state_ == kExpectKey);
- if (!first_element_) {
- stream_ << ", ";
- }
- stream_ << "\"" << key << "\": ";
- state_ = kExpectValue;
- first_element_ = false;
- }
- void AddValue(const char* value) {
- assert(state_ == kExpectValue || state_ == kInArray);
- if (state_ == kInArray && !first_element_) {
- stream_ << ", ";
- }
- stream_ << "\"" << value << "\"";
- if (state_ != kInArray) {
- state_ = kExpectKey;
- }
- first_element_ = false;
- }
- template <typename T>
- void AddValue(const T& value) {
- assert(state_ == kExpectValue || state_ == kInArray);
- if (state_ == kInArray && !first_element_) {
- stream_ << ", ";
- }
- stream_ << value;
- if (state_ != kInArray) {
- state_ = kExpectKey;
- }
- first_element_ = false;
- }
- void StartArray() {
- assert(state_ == kExpectValue);
- state_ = kInArray;
- in_array_ = true;
- stream_ << "[";
- first_element_ = true;
- }
- void EndArray() {
- assert(state_ == kInArray);
- state_ = kExpectKey;
- in_array_ = false;
- stream_ << "]";
- first_element_ = false;
- }
- void StartObject() {
- assert(state_ == kExpectValue);
- state_ = kExpectKey;
- stream_ << "{";
- first_element_ = true;
- }
- void EndObject() {
- assert(state_ == kExpectKey);
- stream_ << "}";
- first_element_ = false;
- }
- void StartArrayedObject() {
- assert(state_ == kInArray && in_array_);
- state_ = kExpectValue;
- if (!first_element_) {
- stream_ << ", ";
- }
- StartObject();
- }
- void EndArrayedObject() {
- assert(in_array_);
- EndObject();
- state_ = kInArray;
- }
- std::string Get() const { return stream_.str(); }
- JSONWriter& operator<<(const char* val) {
- if (state_ == kExpectKey) {
- AddKey(val);
- } else {
- AddValue(val);
- }
- return *this;
- }
- JSONWriter& operator<<(const std::string& val) {
- return *this << val.c_str();
- }
- template <typename T>
- JSONWriter& operator<<(const T& val) {
- assert(state_ != kExpectKey);
- AddValue(val);
- return *this;
- }
- private:
- enum JSONWriterState {
- kExpectKey,
- kExpectValue,
- kInArray,
- kInArrayedObject,
- };
- JSONWriterState state_;
- bool first_element_;
- bool in_array_;
- std::ostringstream stream_;
- };
- class EventLoggerStream {
- public:
- template <typename T>
- EventLoggerStream& operator<<(const T& val) {
- MakeStream();
- *json_writer_ << val;
- return *this;
- }
- void StartArray() { json_writer_->StartArray(); }
- void EndArray() { json_writer_->EndArray(); }
- void StartObject() { json_writer_->StartObject(); }
- void EndObject() { json_writer_->EndObject(); }
- ~EventLoggerStream();
- private:
- void MakeStream() {
- if (!json_writer_) {
- json_writer_ = new JSONWriter();
- *this << "time_micros"
- << std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::system_clock::now().time_since_epoch()).count();
- }
- }
- friend class EventLogger;
- explicit EventLoggerStream(Logger* logger);
- explicit EventLoggerStream(LogBuffer* log_buffer, const size_t max_log_size);
- // exactly one is non-nullptr
- Logger* const logger_;
- LogBuffer* const log_buffer_;
- const size_t max_log_size_; // used only for log_buffer_
- // ownership
- JSONWriter* json_writer_;
- };
- // here is an example of the output that will show up in the LOG:
- // 2015/01/15-14:13:25.788019 1105ef000 EVENT_LOG_v1 {"time_micros":
- // 1421360005788015, "event": "table_file_creation", "file_number": 12,
- // "file_size": 1909699}
- class EventLogger {
- public:
- static const char* Prefix() {
- return "EVENT_LOG_v1";
- }
- explicit EventLogger(Logger* logger) : logger_(logger) {}
- EventLoggerStream Log() { return EventLoggerStream(logger_); }
- EventLoggerStream LogToBuffer(LogBuffer* log_buffer) {
- return EventLoggerStream(log_buffer, LogBuffer::kDefaultMaxLogSize);
- }
- EventLoggerStream LogToBuffer(LogBuffer* log_buffer,
- const size_t max_log_size) {
- return EventLoggerStream(log_buffer, max_log_size);
- }
- void Log(const JSONWriter& jwriter);
- static void Log(Logger* logger, const JSONWriter& jwriter);
- static void LogToBuffer(
- LogBuffer* log_buffer, const JSONWriter& jwriter,
- const size_t max_log_size = LogBuffer::kDefaultMaxLogSize);
- private:
- Logger* logger_;
- };
- } // namespace ROCKSDB_NAMESPACE
|