mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-10 06:05:49 +00:00
300 lines
8.1 KiB
C++
300 lines
8.1 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of rippled: https://github.com/ripple/rippled
|
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef RIPPLE_BASICS_LOG_H_INCLUDED
|
|
#define RIPPLE_BASICS_LOG_H_INCLUDED
|
|
|
|
#include <xrpl/basics/UnorderedContainers.h>
|
|
#include <xrpl/beast/utility/Journal.h>
|
|
|
|
#include <boost/beast/core/string.hpp>
|
|
#include <boost/filesystem.hpp>
|
|
|
|
#include <fstream>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <utility>
|
|
|
|
namespace ripple {
|
|
|
|
// DEPRECATED use beast::severities::Severity instead
|
|
enum LogSeverity {
|
|
lsINVALID = -1, // used to indicate an invalid severity
|
|
lsTRACE = 0, // Very low-level progress information, details inside
|
|
// an operation
|
|
lsDEBUG = 1, // Function-level progress information, operations
|
|
lsINFO = 2, // Server-level progress information, major operations
|
|
lsWARNING = 3, // Conditions that warrant human attention, may indicate
|
|
// a problem
|
|
lsERROR = 4, // A condition that indicates a problem
|
|
lsFATAL = 5 // A severe condition that indicates a server problem
|
|
};
|
|
|
|
/** Manages partitions for logging. */
|
|
class Logs
|
|
{
|
|
private:
|
|
class Sink : public beast::Journal::Sink
|
|
{
|
|
private:
|
|
Logs& logs_;
|
|
std::string partition_;
|
|
|
|
public:
|
|
Sink(
|
|
std::string const& partition,
|
|
beast::severities::Severity thresh,
|
|
Logs& logs);
|
|
|
|
Sink(Sink const&) = delete;
|
|
Sink&
|
|
operator=(Sink const&) = delete;
|
|
|
|
void
|
|
write(beast::severities::Severity level, std::string&& text)
|
|
override;
|
|
|
|
void
|
|
writeAlways(beast::severities::Severity level, std::string&& text)
|
|
override;
|
|
};
|
|
|
|
/** Manages a system file containing logged output.
|
|
The system file remains open during program execution. Interfaces
|
|
are provided for interoperating with standard log management
|
|
tools like logrotate(8):
|
|
http://linuxcommand.org/man_pages/logrotate8.html
|
|
@note None of the listed interfaces are thread-safe.
|
|
*/
|
|
class File
|
|
{
|
|
public:
|
|
/** Construct with no associated system file.
|
|
A system file may be associated later with @ref open.
|
|
@see open
|
|
*/
|
|
File();
|
|
|
|
/** Destroy the object.
|
|
If a system file is associated, it will be flushed and closed.
|
|
*/
|
|
~File() = default;
|
|
|
|
/** Determine if a system file is associated with the log.
|
|
@return `true` if a system file is associated and opened for
|
|
writing.
|
|
*/
|
|
bool
|
|
isOpen() const noexcept;
|
|
|
|
/** Associate a system file with the log.
|
|
If the file does not exist an attempt is made to create it
|
|
and open it for writing. If the file already exists an attempt is
|
|
made to open it for appending.
|
|
If a system file is already associated with the log, it is closed
|
|
first.
|
|
@return `true` if the file was opened.
|
|
*/
|
|
bool
|
|
open(boost::filesystem::path const& path);
|
|
|
|
/** Close and re-open the system file associated with the log
|
|
This assists in interoperating with external log management tools.
|
|
@return `true` if the file was opened.
|
|
*/
|
|
bool
|
|
closeAndReopen();
|
|
|
|
/** Close the system file if it is open. */
|
|
void
|
|
close();
|
|
|
|
/** write to the log file.
|
|
Does nothing if there is no associated system file.
|
|
*/
|
|
void
|
|
write(char const* text);
|
|
|
|
/** write to the log file and append an end of line marker.
|
|
Does nothing if there is no associated system file.
|
|
*/
|
|
void
|
|
writeln(char const* text);
|
|
|
|
/** Write to the log file using std::string. */
|
|
/** @{ */
|
|
void
|
|
write(std::string const& str)
|
|
{
|
|
write(str.c_str());
|
|
}
|
|
|
|
void
|
|
writeln(std::string const& str)
|
|
{
|
|
writeln(str.c_str());
|
|
}
|
|
/** @} */
|
|
|
|
private:
|
|
std::unique_ptr<std::ofstream> m_stream;
|
|
boost::filesystem::path m_path;
|
|
std::mutex mutable fileMutex_;
|
|
};
|
|
|
|
std::mutex mutable sinkSetMutex_;
|
|
std::map<
|
|
std::string,
|
|
std::unique_ptr<beast::Journal::Sink>,
|
|
boost::beast::iless>
|
|
sinks_;
|
|
beast::severities::Severity thresh_;
|
|
File file_;
|
|
bool silent_ = false;
|
|
|
|
public:
|
|
Logs(beast::severities::Severity level);
|
|
|
|
Logs(Logs const&) = delete;
|
|
Logs&
|
|
operator=(Logs const&) = delete;
|
|
|
|
virtual ~Logs() = default;
|
|
|
|
bool
|
|
open(boost::filesystem::path const& pathToLogFile);
|
|
|
|
beast::Journal::Sink&
|
|
get(std::string const& name);
|
|
|
|
beast::Journal::Sink&
|
|
operator[](std::string const& name);
|
|
|
|
beast::Journal
|
|
journal(
|
|
std::string const& name,
|
|
std::optional<beast::Journal::JsonLogAttributes> attributes =
|
|
std::nullopt);
|
|
|
|
beast::severities::Severity
|
|
threshold() const;
|
|
|
|
void
|
|
threshold(beast::severities::Severity thresh);
|
|
|
|
std::vector<std::pair<std::string, std::string>>
|
|
partition_severities() const;
|
|
|
|
void
|
|
write(
|
|
beast::severities::Severity level,
|
|
std::string const& partition,
|
|
std::string const& text,
|
|
bool console);
|
|
|
|
std::string
|
|
rotate();
|
|
|
|
/**
|
|
* Set flag to write logs to stderr (false) or not (true).
|
|
*
|
|
* @param bSilent Set flag accordingly.
|
|
*/
|
|
void
|
|
silent(bool bSilent)
|
|
{
|
|
silent_ = bSilent;
|
|
}
|
|
|
|
virtual std::unique_ptr<beast::Journal::Sink>
|
|
makeSink(
|
|
std::string const& partition,
|
|
beast::severities::Severity startingLevel);
|
|
|
|
public:
|
|
static LogSeverity
|
|
fromSeverity(beast::severities::Severity level);
|
|
|
|
static beast::severities::Severity
|
|
toSeverity(LogSeverity level);
|
|
|
|
static std::string
|
|
toString(LogSeverity s);
|
|
|
|
static LogSeverity
|
|
fromString(std::string const& s);
|
|
|
|
static void
|
|
format(
|
|
std::string& output,
|
|
std::string const& message,
|
|
beast::severities::Severity severity,
|
|
std::string const& partition);
|
|
|
|
private:
|
|
enum {
|
|
// Maximum line length for log messages.
|
|
// If the message exceeds this length it will be truncated with elipses.
|
|
maximumMessageCharacters = 12 * 1024
|
|
};
|
|
};
|
|
|
|
// Wraps a Journal::Stream to skip evaluation of
|
|
// expensive argument lists if the stream is not active.
|
|
#ifndef JLOG
|
|
#define JLOG(x) \
|
|
if (!x) \
|
|
{ \
|
|
} \
|
|
else \
|
|
x
|
|
#endif
|
|
|
|
#ifndef CLOG
|
|
#define CLOG(ss) \
|
|
if (!ss) \
|
|
; \
|
|
else \
|
|
*ss
|
|
#endif
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Debug logging:
|
|
|
|
/** Set the sink for the debug journal.
|
|
|
|
@param sink unique_ptr to new debug Sink.
|
|
@return unique_ptr to the previous Sink. nullptr if there was no Sink.
|
|
*/
|
|
std::unique_ptr<beast::Journal::Sink>
|
|
setDebugLogSink(std::unique_ptr<beast::Journal::Sink> sink);
|
|
|
|
/** Returns a debug journal.
|
|
The journal may drain to a null sink, so its output
|
|
may never be seen. Never use it for critical
|
|
information.
|
|
*/
|
|
beast::Journal
|
|
debugLog();
|
|
|
|
} // namespace ripple
|
|
|
|
#endif
|