311 lines
9.3 KiB
C++
311 lines
9.3 KiB
C++
/**
|
|
* Orthanc - A Lightweight, RESTful DICOM Store
|
|
* Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
|
|
* Department, University Hospital of Liege, Belgium
|
|
* Copyright (C) 2017-2023 Osimis S.A., Belgium
|
|
* Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
|
|
* Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
|
|
*
|
|
* This program is free software: you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation, either version 3 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this program. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
**/
|
|
|
|
|
|
#pragma once
|
|
|
|
// To have ORTHANC_ENABLE_LOGGING defined if using the shared library
|
|
#include "OrthancFramework.h"
|
|
#include "Compatibility.h"
|
|
|
|
#include <iostream>
|
|
#include <stdint.h>
|
|
|
|
#if !defined(ORTHANC_ENABLE_LOGGING)
|
|
# error The macro ORTHANC_ENABLE_LOGGING must be defined
|
|
#endif
|
|
|
|
#if !defined(ORTHANC_ENABLE_LOGGING_STDIO)
|
|
# if ORTHANC_ENABLE_LOGGING == 1
|
|
# error The macro ORTHANC_ENABLE_LOGGING_STDIO must be defined
|
|
# else
|
|
# define ORTHANC_ENABLE_LOGGING_STDIO 0
|
|
# endif
|
|
#endif
|
|
|
|
|
|
namespace Orthanc
|
|
{
|
|
namespace Logging
|
|
{
|
|
// Note: these values must match the ones in OrthancCPlugin.h
|
|
enum LogLevel
|
|
{
|
|
LogLevel_ERROR = 0,
|
|
LogLevel_WARNING = 1,
|
|
LogLevel_INFO = 2,
|
|
LogLevel_TRACE = 3
|
|
};
|
|
|
|
/**
|
|
* NB: The log level for each category is encoded as a bit
|
|
* mask. As a consequence, there can be up to 31 log categories
|
|
* (not 32, as the value GENERIC is reserved for the log commands
|
|
* that don't fall in a specific category).
|
|
* Note: these values must match the ones in OrthancCPlugin.h
|
|
**/
|
|
enum LogCategory
|
|
{
|
|
LogCategory_GENERIC = (1 << 0),
|
|
LogCategory_PLUGINS = (1 << 1),
|
|
LogCategory_HTTP = (1 << 2),
|
|
LogCategory_SQLITE = (1 << 3),
|
|
LogCategory_DICOM = (1 << 4),
|
|
LogCategory_JOBS = (1 << 5),
|
|
LogCategory_LUA = (1 << 6)
|
|
};
|
|
|
|
ORTHANC_PUBLIC const char* EnumerationToString(LogLevel level);
|
|
|
|
ORTHANC_PUBLIC LogLevel StringToLogLevel(const char* level);
|
|
|
|
// "pluginContext" must be of type "OrthancPluginContext"
|
|
ORTHANC_PUBLIC void InitializePluginContext(void* pluginContext);
|
|
|
|
ORTHANC_PUBLIC void InitializePluginContext(void* pluginContext,
|
|
const std::string& pluginName);
|
|
|
|
ORTHANC_PUBLIC void Initialize();
|
|
|
|
ORTHANC_PUBLIC void Finalize();
|
|
|
|
ORTHANC_PUBLIC void Reset();
|
|
|
|
ORTHANC_PUBLIC void Flush();
|
|
|
|
ORTHANC_PUBLIC void SetCurrentThreadName(const std::string& name);
|
|
|
|
ORTHANC_PUBLIC bool HasCurrentThreadName();
|
|
|
|
ORTHANC_PUBLIC void EnableThreadNames(bool enabled);
|
|
|
|
ORTHANC_PUBLIC void EnableInfoLevel(bool enabled);
|
|
|
|
ORTHANC_PUBLIC void EnableTraceLevel(bool enabled);
|
|
|
|
ORTHANC_PUBLIC bool IsTraceLevelEnabled();
|
|
|
|
ORTHANC_PUBLIC bool IsInfoLevelEnabled();
|
|
|
|
ORTHANC_PUBLIC void SetCategoryEnabled(LogLevel level,
|
|
LogCategory category,
|
|
bool enabled);
|
|
|
|
ORTHANC_PUBLIC bool IsCategoryEnabled(LogLevel level,
|
|
LogCategory category);
|
|
|
|
ORTHANC_PUBLIC bool LookupCategory(LogCategory& target,
|
|
const std::string& category);
|
|
|
|
ORTHANC_PUBLIC unsigned int GetCategoriesCount();
|
|
|
|
ORTHANC_PUBLIC const char* GetCategoryName(unsigned int i);
|
|
|
|
ORTHANC_PUBLIC const char* GetCategoryName(LogCategory category);
|
|
|
|
ORTHANC_PUBLIC void SetTargetFile(const std::string& path);
|
|
|
|
ORTHANC_PUBLIC void SetTargetFolder(const std::string& path);
|
|
|
|
struct ORTHANC_LOCAL NullStream : public std::ostream
|
|
{
|
|
NullStream() :
|
|
std::ios(0),
|
|
std::ostream(0)
|
|
{
|
|
}
|
|
|
|
template <typename T>
|
|
std::ostream& operator<< (const T& message)
|
|
{
|
|
return *this;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* NB:
|
|
* - The "VLOG(unused)" macro is for backward compatibility with
|
|
* Orthanc <= 1.8.0.
|
|
* - The "CLOG()" macro stands for "category log" (new in Orthanc 1.8.1)
|
|
**/
|
|
|
|
#if defined(LOG)
|
|
# error The macro LOG cannot be defined beforehand
|
|
#endif
|
|
|
|
#if defined(VLOG)
|
|
# error The macro VLOG cannot be defined beforehand
|
|
#endif
|
|
|
|
#if defined(CLOG)
|
|
# error The macro CLOG cannot be defined beforehand
|
|
#endif
|
|
|
|
#if ORTHANC_ENABLE_LOGGING != 1
|
|
# define LOG(level) ::Orthanc::Logging::NullStream()
|
|
# define VLOG(unused) ::Orthanc::Logging::NullStream()
|
|
# define CLOG(level, category) ::Orthanc::Logging::NullStream()
|
|
# define LOG_FROM_PLUGIN(level, category, pluginName, file, line) ::Orthanc::Logging::NullStream()
|
|
#else /* ORTHANC_ENABLE_LOGGING == 1 */
|
|
|
|
#if !defined(__ORTHANC_FILE__)
|
|
# if defined(_MSC_VER)
|
|
# pragma message("Warning: Macro __ORTHANC_FILE__ is not defined, this will leak the full path of the source files in the binaries")
|
|
# else
|
|
# warning Warning: Macro __ORTHANC_FILE__ is not defined, this will leak the full path of the source files in the binaries
|
|
# endif
|
|
# define __ORTHANC_FILE__ __FILE__
|
|
#endif
|
|
|
|
# define LOG(level) ::Orthanc::Logging::InternalLogger \
|
|
(::Orthanc::Logging::LogLevel_ ## level, \
|
|
::Orthanc::Logging::LogCategory_GENERIC, NULL /* no plugin */, \
|
|
__ORTHANC_FILE__, __LINE__)
|
|
|
|
# define VLOG(unused) ::Orthanc::Logging::InternalLogger \
|
|
(::Orthanc::Logging::LogLevel_TRACE, \
|
|
::Orthanc::Logging::LogCategory_GENERIC, NULL /* no plugin */, \
|
|
__ORTHANC_FILE__, __LINE__)
|
|
|
|
# define CLOG(level, category) ::Orthanc::Logging::InternalLogger \
|
|
(::Orthanc::Logging::LogLevel_ ## level, \
|
|
::Orthanc::Logging::LogCategory_ ## category, NULL /* no plugin */, \
|
|
__ORTHANC_FILE__, __LINE__)
|
|
|
|
# define LOG_FROM_PLUGIN(level, category, pluginName, file, line) \
|
|
::Orthanc::Logging::InternalLogger(level, category, pluginName, file, line)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (ORTHANC_ENABLE_LOGGING == 1 && \
|
|
ORTHANC_ENABLE_LOGGING_STDIO == 1)
|
|
// This is notably for WebAssembly
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
#include <boost/noncopyable.hpp>
|
|
#include <sstream>
|
|
|
|
namespace Orthanc
|
|
{
|
|
namespace Logging
|
|
{
|
|
class ORTHANC_PUBLIC InternalLogger : public boost::noncopyable
|
|
{
|
|
private:
|
|
LogLevel level_;
|
|
LogCategory category_;
|
|
std::stringstream messageStream_;
|
|
|
|
public:
|
|
InternalLogger(LogLevel level,
|
|
LogCategory category,
|
|
const char* pluginName /* ignored */,
|
|
const char* file /* ignored */,
|
|
int line /* ignored */) :
|
|
level_(level),
|
|
category_(category)
|
|
{
|
|
}
|
|
|
|
~InternalLogger();
|
|
|
|
template <typename T>
|
|
std::ostream& operator<< (const T& message)
|
|
{
|
|
return messageStream_ << boost::lexical_cast<std::string>(message);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (ORTHANC_ENABLE_LOGGING == 1 && \
|
|
ORTHANC_ENABLE_LOGGING_STDIO == 0)
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
#include <boost/noncopyable.hpp>
|
|
#include <boost/thread/mutex.hpp>
|
|
#include <sstream>
|
|
|
|
namespace Orthanc
|
|
{
|
|
namespace Logging
|
|
{
|
|
class ORTHANC_PUBLIC InternalLogger : public boost::noncopyable
|
|
{
|
|
private:
|
|
boost::mutex::scoped_lock lock_;
|
|
LogLevel level_;
|
|
std::unique_ptr<std::stringstream> pluginStream_;
|
|
std::ostream* stream_;
|
|
LogCategory category_;
|
|
const char* file_;
|
|
uint32_t line_;
|
|
|
|
public:
|
|
InternalLogger(LogLevel level,
|
|
LogCategory category,
|
|
const char* pluginName,
|
|
const char* file,
|
|
int line);
|
|
|
|
~InternalLogger();
|
|
|
|
template <typename T>
|
|
std::ostream& operator<< (const T& message)
|
|
{
|
|
return (*stream_) << boost::lexical_cast<std::string>(message);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Set custom logging streams for the error, warning and info
|
|
* logs. This function may not be called if a log file or folder
|
|
* has been set beforehand. All three references must be valid.
|
|
*
|
|
* Please ensure the supplied streams remain alive and valid as
|
|
* long as logging calls are performed. In order to prevent
|
|
* dangling pointer usage, it is mandatory to call
|
|
* Orthanc::Logging::Reset() before the stream objects are
|
|
* destroyed and the references become invalid.
|
|
*
|
|
* This function must only be used by unit tests. It is ignored if
|
|
* InitializePluginContext() was called.
|
|
**/
|
|
ORTHANC_PUBLIC void SetErrorWarnInfoLoggingStreams(std::ostream& errorStream,
|
|
std::ostream& warningStream,
|
|
std::ostream& infoStream);
|
|
}
|
|
}
|
|
|
|
#endif
|