# HG changeset patch # User Sebastien Jodogne # Date 1604402690 -3600 # Node ID 0034f855c02309c49e7ae6bb66742715275f598e # Parent 1661544ea94d0de40cace0104d528b9183e786c1 tuning log categories from command-line, and binary compat with orthanc framework 1.7.2 diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/ChunkedBuffer.cpp --- a/OrthancFramework/Sources/ChunkedBuffer.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/ChunkedBuffer.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -83,6 +83,18 @@ } + ChunkedBuffer::~ChunkedBuffer() + { + Clear(); + } + + + size_t ChunkedBuffer::GetNumBytes() const + { + return numBytes_ + pendingPos_; + } + + void ChunkedBuffer::SetPendingBufferSize(size_t size) { FlushPendingBuffer(); @@ -90,6 +102,12 @@ } + size_t ChunkedBuffer::GetPendingBufferSize() const + { + return pendingBuffer_.size(); + } + + void ChunkedBuffer::AddChunk(const void* chunkData, size_t chunkSize) { diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/ChunkedBuffer.h --- a/OrthancFramework/Sources/ChunkedBuffer.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/ChunkedBuffer.h Tue Nov 03 12:24:50 2020 +0100 @@ -50,22 +50,13 @@ public: ChunkedBuffer(); - ~ChunkedBuffer() - { - Clear(); - } + ~ChunkedBuffer(); - size_t GetNumBytes() const - { - return numBytes_ + pendingPos_; - } + size_t GetNumBytes() const; void SetPendingBufferSize(size_t size); - size_t GetPendingBufferSize() const - { - return pendingBuffer_.size(); - } + size_t GetPendingBufferSize() const; void AddChunk(const void* chunkData, size_t chunkSize); diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomControlUserConnection.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -76,7 +76,7 @@ if (payload.isWorklist) { - ParsedDicomFile answer(*responseIdentifiers); + const ParsedDicomFile answer(*responseIdentifiers); payload.answers->Add(answer); } else diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp --- a/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -180,7 +180,9 @@ bool simplify) const { DicomToJsonFormat format = (simplify ? DicomToJsonFormat_Human : DicomToJsonFormat_Full); - GetAnswer(index).DatasetToJson(target, format, DicomToJsonFlags_None, 0); + + const ParsedDicomFile& answer = GetAnswer(index); + answer.DatasetToJson(target, format, DicomToJsonFlags_None, 0); } @@ -196,4 +198,12 @@ target.append(answer); } } + + +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + void DicomFindAnswers::Add(ParsedDicomFile& dicom) + { + return Add(const_cast(dicom)); + } +#endif } diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h --- a/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomNetworking/DicomFindAnswers.h Tue Nov 03 12:24:50 2020 +0100 @@ -36,6 +36,11 @@ void AddAnswerInternal(ParsedDicomFile* answer); +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore + void Add(ParsedDicomFile& dicom); +#endif + public: explicit DicomFindAnswers(bool isWorklist); diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomParsing/DicomModification.cpp --- a/OrthancFramework/Sources/DicomParsing/DicomModification.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomParsing/DicomModification.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -328,7 +328,7 @@ } std::string original; - if (!dicom.GetTagValue(original, *tag)) + if (!const_cast(dicom).GetTagValue(original, *tag)) { original = ""; } @@ -1017,7 +1017,7 @@ { std::string original; std::string replacement = GetReplacementAsString(DICOM_TAG_STUDY_INSTANCE_UID); - toModify.GetTagValue(original, DICOM_TAG_STUDY_INSTANCE_UID); + const_cast(toModify).GetTagValue(original, DICOM_TAG_STUDY_INSTANCE_UID); RegisterMappedDicomIdentifier(original, replacement, ResourceType_Study); } @@ -1025,7 +1025,7 @@ { std::string original; std::string replacement = GetReplacementAsString(DICOM_TAG_SERIES_INSTANCE_UID); - toModify.GetTagValue(original, DICOM_TAG_SERIES_INSTANCE_UID); + const_cast(toModify).GetTagValue(original, DICOM_TAG_SERIES_INSTANCE_UID); RegisterMappedDicomIdentifier(original, replacement, ResourceType_Series); } @@ -1033,7 +1033,7 @@ { std::string original; std::string replacement = GetReplacementAsString(DICOM_TAG_SOP_INSTANCE_UID); - toModify.GetTagValue(original, DICOM_TAG_SOP_INSTANCE_UID); + const_cast(toModify).GetTagValue(original, DICOM_TAG_SOP_INSTANCE_UID); RegisterMappedDicomIdentifier(original, replacement, ResourceType_Instance); } } @@ -1114,7 +1114,7 @@ if (updateReferencedRelationships_) { - toModify.Apply(visitor); + const_cast(toModify).Apply(visitor); } else { diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp --- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -1018,4 +1018,13 @@ writer.WriteToMemory(result, *image); } #endif + + +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + ImageAccessor *DicomImageDecoder::Decode(ParsedDicomFile& dataset, + unsigned int frame) + { + return Decode(*dataset.GetDcmtkObject().getDataset(), frame); + } +#endif } diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h --- a/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h Tue Nov 03 12:24:50 2020 +0100 @@ -84,6 +84,12 @@ ImageExtractionMode mode, bool invert); +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore + static ImageAccessor *Decode(ParsedDicomFile& dataset, + unsigned int frame); +#endif + public: static bool IsPsmctRle1(DcmDataset& dataset); diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp --- a/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomParsing/MemoryBufferTranscoder.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -41,7 +41,7 @@ std::string s; DicomTransferSyntax a, b; - if (!parsed.LookupTransferSyntax(s) || + if (!const_cast(parsed).LookupTransferSyntax(s) || !FromDcmtkBridge::LookupOrthancTransferSyntax(a, parsed.GetDcmtkObject()) || !LookupTransferSyntax(b, s) || a != b || diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp --- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -1733,4 +1733,42 @@ return DicomImageDecoder::Decode(*GetDcmtkObjectConst().getDataset(), frame); } } + + +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore + void ParsedDicomFile::DatasetToJson(Json::Value& target, + DicomToJsonFormat format, + DicomToJsonFlags flags, + unsigned int maxStringLength) + { + return const_cast(*this).DatasetToJson(target, format, flags, maxStringLength); + } + + DcmFileFormat& ParsedDicomFile::GetDcmtkObject() const + { + return const_cast(*this).GetDcmtkObject(); + } + + void ParsedDicomFile::Apply(ITagVisitor& visitor) + { + const_cast(*this).Apply(visitor); + } + + ParsedDicomFile* ParsedDicomFile::Clone(bool keepSopInstanceUid) + { + return const_cast(*this).Clone(keepSopInstanceUid); + } + + bool ParsedDicomFile::LookupTransferSyntax(std::string& result) + { + return const_cast(*this).LookupTransferSyntax(result); + } + + bool ParsedDicomFile::GetTagValue(std::string& value, + const DicomTag& tag) + { + return const_cast(*this).GetTagValue(value, tag); + } +#endif } diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h --- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h Tue Nov 03 12:24:50 2020 +0100 @@ -101,6 +101,20 @@ explicit ParsedDicomFile(DcmFileFormat* dicom); // This takes ownership (no clone) +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore + void DatasetToJson(Json::Value& target, + DicomToJsonFormat format, + DicomToJsonFlags flags, + unsigned int maxStringLength); + DcmFileFormat& GetDcmtkObject() const; + void Apply(ITagVisitor& visitor); + ParsedDicomFile* Clone(bool keepSopInstanceUid); + bool LookupTransferSyntax(std::string& result); + bool GetTagValue(std::string& value, + const DicomTag& tag); +#endif + public: explicit ParsedDicomFile(bool createIdentifiers); // Create a minimal DICOM instance diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp --- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -260,4 +260,13 @@ { return boost::filesystem::space(root_).available; } + + +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + FilesystemStorage::FilesystemStorage(std::string root) : + fsyncOnWrite_(false) + { + Setup(root); + } +#endif } diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/FileStorage/FilesystemStorage.h --- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.h Tue Nov 03 12:24:50 2020 +0100 @@ -55,6 +55,11 @@ void Setup(const std::string& root); +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore + explicit FilesystemStorage(std::string root); +#endif + public: explicit FilesystemStorage(const std::string& root) : fsyncOnWrite_(false) diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/HttpServer/HttpServer.cpp --- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -1088,7 +1088,7 @@ std::transform(name.begin(), name.end(), name.begin(), ::tolower); headers.insert(std::make_pair(name, value)); - LOG(TRACE) << "HTTP header: [" << name << "]: [" << value << "]"; + CLOG(TRACE, REST) << "HTTP header: [" << name << "]: [" << value << "]"; } if (server.IsHttpCompressionEnabled()) diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/Images/ImageAccessor.cpp --- a/OrthancFramework/Sources/Images/ImageAccessor.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/Images/ImageAccessor.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -90,7 +90,7 @@ target.AddChunk("], [ 3 " + boost::lexical_cast(source.GetHeight()) + " " + boost::lexical_cast(source.GetWidth()) + " ]), [ 3 2 1 ]))"); } - + void* ImageAccessor::GetBuffer() { @@ -293,4 +293,17 @@ format_ = format; } + + +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + void* ImageAccessor::GetBuffer() const + { + return const_cast(*this).GetBuffer(); + } + + void* ImageAccessor::GetRow(unsigned int y) const + { + return const_cast(*this).GetRow(y); + } +#endif } diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/Images/ImageAccessor.h --- a/OrthancFramework/Sources/Images/ImageAccessor.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/Images/ImageAccessor.h Tue Nov 03 12:24:50 2020 +0100 @@ -22,6 +22,7 @@ #pragma once +#include "../Compatibility.h" #include "../Enumerations.h" #include @@ -60,6 +61,12 @@ return reinterpret_cast(row) [x]; } +#if ORTHANC_BUILDING_FRAMEWORK_LIBRARY == 1 + // Alias for binary compatibility with Orthanc Framework 1.7.2 => don't use it anymore + void* GetBuffer() const; + void* GetRow(unsigned int y) const; +#endif + public: ImageAccessor() { diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/Logging.cpp --- a/OrthancFramework/Sources/Logging.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/Logging.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -193,32 +193,68 @@ } - LogCategory StringToCategory(const std::string& category) + bool LookupCategory(LogCategory& target, + const std::string& category) { if (category == "generic") { - return LogCategory_GENERIC; + target = LogCategory_GENERIC; + return true; } else if (category == "plugins") { - return LogCategory_PLUGINS; + target = LogCategory_PLUGINS; + return true; } else if (category == "rest") { - return LogCategory_REST; + target = LogCategory_REST; + return true; } else if (category == "dicom") { - return LogCategory_DICOM; + target = LogCategory_DICOM; + return true; } else if (category == "sqlite") { - return LogCategory_SQLITE; + target = LogCategory_SQLITE; + return true; } else { - throw OrthancException(ErrorCode_ParameterOutOfRange, - "Unknown log category: " + category); + return false; + } + } + + + size_t GetCategoriesCount() + { + return 5; + } + + + const char* GetCategoryName(size_t i) + { + switch (i) + { + case 0: + return "generic"; + + case 1: + return "plugins"; + + case 2: + return "rest"; + + case 3: + return "dicom"; + + case 4: + return "sqlite"; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); } } } @@ -709,20 +745,16 @@ } - InternalLogger::InternalLogger(LogLevel level, - LogCategory category, - const char* file, - int line) : - lock_(loggingStreamsMutex_, boost::defer_lock_t()), - level_(level), - stream_(&nullStream_) // By default, logging to "/dev/null" is simulated + void InternalLogger::Setup(LogCategory category, + const char* file, + int line) { if (pluginContext_ != NULL) { // We are logging using the Orthanc plugin SDK - if (level == LogLevel_TRACE || - !IsCategoryEnabled(level, category)) + if (level_ == LogLevel_TRACE || + !IsCategoryEnabled(level_, category)) { // No trace level in plugins, directly exit as the stream is // set to "/dev/null" @@ -738,7 +770,7 @@ { // We are logging in a standalone application, not inside an Orthanc plugin - if (!IsCategoryEnabled(level, category)) + if (!IsCategoryEnabled(level_, category)) { // This logging level is disabled, directly exit as the // stream is set to "/dev/null" @@ -746,7 +778,7 @@ } std::string prefix; - GetLinePrefix(prefix, level, file, line); + GetLinePrefix(prefix, level_, file, line); { // We lock the global mutex. The mutex is locked until the @@ -760,7 +792,7 @@ return; } - switch (level) + switch (level_) { case LogLevel_ERROR: stream_ = loggingStreamsContext_->error_; @@ -805,6 +837,29 @@ } + InternalLogger::InternalLogger(LogLevel level, + LogCategory category, + const char* file, + int line) : + lock_(loggingStreamsMutex_, boost::defer_lock_t()), + level_(level), + stream_(&nullStream_) // By default, logging to "/dev/null" is simulated + { + Setup(category, file, line); + } + + + InternalLogger::InternalLogger(LogLevel level, + const char* file, + int line) : + lock_(loggingStreamsMutex_, boost::defer_lock_t()), + level_(level), + stream_(&nullStream_) // By default, logging to "/dev/null" is simulated + { + Setup(LogCategory_GENERIC, file, line); + } + + InternalLogger::~InternalLogger() { if (pluginStream_.get() != NULL) diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/Logging.h --- a/OrthancFramework/Sources/Logging.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/Logging.h Tue Nov 03 12:24:50 2020 +0100 @@ -97,7 +97,12 @@ ORTHANC_PUBLIC bool IsCategoryEnabled(LogLevel level, LogCategory category); - ORTHANC_PUBLIC LogCategory StringToCategory(const std::string& category); + ORTHANC_PUBLIC bool LookupCategory(LogCategory& target, + const std::string& category); + + ORTHANC_PUBLIC size_t GetCategoriesCount(); + + ORTHANC_PUBLIC const char* GetCategoryName(size_t i); ORTHANC_PUBLIC void SetTargetFile(const std::string& path); @@ -146,11 +151,11 @@ # define VLOG(unused) ::Orthanc::Logging::NullStream() # define CLOG(level, category) ::Orthanc::Logging::NullStream() #else /* ORTHANC_ENABLE_LOGGING == 1 */ -# define LOG(level) ::Orthanc::Logging::InternalLogger \ - (::Orthanc::Logging::LogLevel_ ## level, \ +# define LOG(level) ::Orthanc::Logging::InternalLogger \ + (::Orthanc::Logging::LogLevel_ ## level, \ ::Orthanc::Logging::LogCategory_GENERIC, __FILE__, __LINE__) -# define VLOG(unused) ::Orthanc::Logging::InternalLogger \ - (::Orthanc::Logging::LogLevel_TRACE, \ +# define VLOG(unused) ::Orthanc::Logging::InternalLogger \ + (::Orthanc::Logging::LogLevel_TRACE, \ ::Orthanc::Logging::LogCategory_GENERIC, __FILE__, __LINE__) # define CLOG(level, category) ::Orthanc::Logging::InternalLogger \ (::Orthanc::Logging::LogLevel_ ## level, \ @@ -188,6 +193,15 @@ { } + // For backward binary compatibility with Orthanc Framework <= 1.8.0 + InternalLogger(LogLevel level, + const char* file /* ignored */, + int line /* ignored */) : + level_(level), + category_(LogCategory_GENERIC) + { + } + ~InternalLogger(); template @@ -225,12 +239,21 @@ std::unique_ptr pluginStream_; std::ostream* stream_; + void Setup(LogCategory category, + const char* file, + int line); + public: InternalLogger(LogLevel level, LogCategory category, const char* file, int line); + // For backward binary compatibility with Orthanc Framework <= 1.8.0 + InternalLogger(LogLevel level, + const char* file, + int line); + ~InternalLogger(); template @@ -240,7 +263,6 @@ } }; - /** * Set custom logging streams for the error, warning and info * logs. This function may not be called if a log file or folder diff -r 1661544ea94d -r 0034f855c023 OrthancFramework/Sources/PrecompiledHeaders.h --- a/OrthancFramework/Sources/PrecompiledHeaders.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancFramework/Sources/PrecompiledHeaders.h Tue Nov 03 12:24:50 2020 +0100 @@ -48,8 +48,6 @@ #include "Enumerations.h" #include "Logging.h" #include "OrthancException.h" -#include "OrthancFramework.h" -#include "Toolbox.h" #if ORTHANC_ENABLE_DCMTK == 1 // Headers from DCMTK used in Orthanc headers @@ -60,8 +58,6 @@ #endif #if ORTHANC_ENABLE_DCMTK_NETWORKING == 1 -# include "DicomNetworking/DicomServer.h" - // Headers from DCMTK used in Orthanc headers # include #endif diff -r 1661544ea94d -r 0034f855c023 OrthancServer/Sources/OrthancInitialization.cpp --- a/OrthancServer/Sources/OrthancInitialization.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancServer/Sources/OrthancInitialization.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -394,4 +394,89 @@ { return CreateFilesystemStorage(); } + + + void SetGlobalVerbosity(Verbosity verbosity) + { + switch (verbosity) + { + case Verbosity_Default: + Logging::EnableInfoLevel(false); + Logging::EnableTraceLevel(false); + break; + + case Verbosity_Verbose: + Logging::EnableInfoLevel(true); + Logging::EnableTraceLevel(false); + break; + + case Verbosity_Trace: + Logging::EnableInfoLevel(true); + Logging::EnableTraceLevel(true); + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + + + Verbosity GetGlobalVerbosity() + { + if (Logging::IsTraceLevelEnabled()) + { + return Verbosity_Trace; + } + else if (Logging::IsInfoLevelEnabled()) + { + return Verbosity_Verbose; + } + else + { + return Verbosity_Default; + } + } + + + void SetCategoryVerbosity(Logging::LogCategory category, + Verbosity verbosity) + { + switch (verbosity) + { + case Verbosity_Default: + Logging::SetCategoryEnabled(Logging::LogLevel_INFO, category, false); + Logging::SetCategoryEnabled(Logging::LogLevel_TRACE, category, false); + break; + + case Verbosity_Verbose: + Logging::SetCategoryEnabled(Logging::LogLevel_INFO, category, true); + Logging::SetCategoryEnabled(Logging::LogLevel_TRACE, category, false); + break; + + case Verbosity_Trace: + Logging::SetCategoryEnabled(Logging::LogLevel_INFO, category, true); + Logging::SetCategoryEnabled(Logging::LogLevel_TRACE, category, true); + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + + + Verbosity GetCategoryVerbosity(Logging::LogCategory category) + { + if (Logging::IsCategoryEnabled(Logging::LogLevel_TRACE, category)) + { + return Verbosity_Trace; + } + else if (Logging::IsCategoryEnabled(Logging::LogLevel_INFO, category)) + { + return Verbosity_Verbose; + } + else + { + return Verbosity_Default; + } + } } diff -r 1661544ea94d -r 0034f855c023 OrthancServer/Sources/OrthancInitialization.h --- a/OrthancServer/Sources/OrthancInitialization.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancServer/Sources/OrthancInitialization.h Tue Nov 03 12:24:50 2020 +0100 @@ -34,6 +34,7 @@ #pragma once #include "../../OrthancFramework/Sources/FileStorage/IStorageArea.h" +#include "../../OrthancFramework/Sources/Logging.h" #include "Database/IDatabaseWrapper.h" namespace Orthanc @@ -45,4 +46,13 @@ IDatabaseWrapper* CreateDatabaseWrapper(); IStorageArea* CreateStorageArea(); + + void SetGlobalVerbosity(Verbosity verbosity); + + Verbosity GetGlobalVerbosity(); + + void SetCategoryVerbosity(Logging::LogCategory category, + Verbosity verbosity); + + Verbosity GetCategoryVerbosity(Logging::LogCategory category); } diff -r 1661544ea94d -r 0034f855c023 OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestSystem.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -39,14 +39,10 @@ #include "../../Plugins/Engine/OrthancPlugins.h" #include "../../Plugins/Engine/PluginsManager.h" #include "../OrthancConfiguration.h" +#include "../OrthancInitialization.h" #include "../ServerContext.h" -static const char* LOG_LEVEL_DEFAULT = "default"; -static const char* LOG_LEVEL_VERBOSE = "verbose"; -static const char* LOG_LEVEL_TRACE = "trace"; - - namespace Orthanc { // System information ------------------------------------------------------- @@ -497,21 +493,7 @@ static void GetLogLevel(RestApiGetCall& call) { - std::string s; - - if (Logging::IsTraceLevelEnabled()) - { - s = LOG_LEVEL_TRACE; - } - else if (Logging::IsInfoLevelEnabled()) - { - s = LOG_LEVEL_VERBOSE; - } - else - { - s = LOG_LEVEL_DEFAULT; - } - + const std::string s = EnumerationToString(GetGlobalVerbosity()); call.GetOutput().AnswerBuffer(s, MimeType_PlainText); } @@ -521,30 +503,8 @@ std::string body; call.BodyToString(body); - if (body == LOG_LEVEL_DEFAULT) - { - Logging::EnableInfoLevel(false); - Logging::EnableTraceLevel(false); - } - else if (body == LOG_LEVEL_VERBOSE) - { - Logging::EnableInfoLevel(true); - Logging::EnableTraceLevel(false); - } - else if (body == LOG_LEVEL_TRACE) - { - Logging::EnableInfoLevel(true); - Logging::EnableTraceLevel(true); - } - else - { - throw OrthancException(ErrorCode_ParameterOutOfRange, - "The log level must be one of the following values: \"" + - std::string(LOG_LEVEL_DEFAULT) + "\", \"" + - std::string(LOG_LEVEL_VERBOSE) + "\", of \"" + - std::string(LOG_LEVEL_TRACE) + "\""); - } - + SetGlobalVerbosity(StringToVerbosity(body)); + // Success LOG(WARNING) << "REST API call has switched the log level to: " << body; call.GetOutput().AnswerBuffer("", MimeType_PlainText); diff -r 1661544ea94d -r 0034f855c023 OrthancServer/Sources/ServerEnumerations.cpp --- a/OrthancServer/Sources/ServerEnumerations.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancServer/Sources/ServerEnumerations.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -237,6 +237,28 @@ "should be \"After\", \"Before\" or \"Disabled\": " + value); } } + + + Verbosity StringToVerbosity(const std::string& str) + { + if (str == "default") + { + return Verbosity_Default; + } + else if (str == "verbose") + { + return Verbosity_Verbose; + } + else if (str == "trace") + { + return Verbosity_Trace; + } + else + { + throw OrthancException(ErrorCode_ParameterOutOfRange, + "Verbosity can be \"default\", \"verbose\" or \"trace\": " + str); + } + } std::string GetBasePath(ResourceType type, @@ -367,6 +389,25 @@ } } + + const char* EnumerationToString(Verbosity verbosity) + { + switch (verbosity) + { + case Verbosity_Default: + return "default"; + + case Verbosity_Verbose: + return "verbose"; + + case Verbosity_Trace: + return "trace"; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + bool IsUserMetadata(MetadataType metadata) { diff -r 1661544ea94d -r 0034f855c023 OrthancServer/Sources/ServerEnumerations.h --- a/OrthancServer/Sources/ServerEnumerations.h Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancServer/Sources/ServerEnumerations.h Tue Nov 03 12:24:50 2020 +0100 @@ -40,6 +40,13 @@ namespace Orthanc { + enum Verbosity + { + Verbosity_Default, + Verbosity_Verbose, + Verbosity_Trace + }; + enum SeriesStatus { SeriesStatus_Complete, @@ -194,6 +201,8 @@ BuiltinDecoderTranscoderOrder StringToBuiltinDecoderTranscoderOrder(const std::string& str); + Verbosity StringToVerbosity(const std::string& str); + std::string EnumerationToString(FileContentType type); std::string GetFileContentMime(FileContentType type); @@ -207,5 +216,7 @@ const char* EnumerationToString(ChangeType type); + const char* EnumerationToString(Verbosity verbosity); + bool IsUserMetadata(MetadataType type); } diff -r 1661544ea94d -r 0034f855c023 OrthancServer/Sources/main.cpp --- a/OrthancServer/Sources/main.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancServer/Sources/main.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -642,6 +642,19 @@ << "\t\t\tthe last execution of Orthanc" << std::endl << " --version\t\toutput version information and exit" << std::endl << std::endl + << "Fine-tuning of log categories:" << std::endl; + + for (size_t i = 0; i < Logging::GetCategoriesCount(); i++) + { + const std::string name = Logging::GetCategoryName(i); + std::cout << " --verbose-" << name + << "\tbe verbose in logs of category \"" << name << "\"" << std::endl; + std::cout << " --trace-" << name + << "\tuse highest verbosity for logs of category \"" << name << "\"" << std::endl; + } + + std::cout + << std::endl << "Exit status:" << std::endl << " 0 if success," << std::endl #if defined(_WIN32) @@ -1495,14 +1508,18 @@ } -static void SetLoggingCategories(Logging::LogLevel level, - const std::string& lst) +static bool SetCategoryVerbosity(const Verbosity verbosity, + const std::string& category) { - std::vector categories; - Toolbox::TokenizeString(categories, lst, ':'); - for (size_t i = 0; i < categories.size(); i++) + Logging::LogCategory c; + if (LookupCategory(c, category)) { - Logging::SetCategoryEnabled(level, Logging::StringToCategory(categories[i]), true); + SetCategoryVerbosity(c, verbosity); + return true; + } + else + { + return false; } } @@ -1569,19 +1586,21 @@ } else if (argument == "--verbose") { - Logging::EnableInfoLevel(true); + SetGlobalVerbosity(Verbosity_Verbose); } else if (argument == "--trace") { - Logging::EnableTraceLevel(true); + SetGlobalVerbosity(Verbosity_Trace); } - else if (boost::starts_with(argument, "--verbose=")) // New in Orthanc 1.8.1 + else if (boost::starts_with(argument, "--verbose-") && + SetCategoryVerbosity(Verbosity_Verbose, argument.substr(10))) { - SetLoggingCategories(Logging::LogLevel_INFO, argument.substr(10)); + // New in Orthanc 1.8.1 } - else if (boost::starts_with(argument, "--trace=")) // New in Orthanc 1.8.1 + else if (boost::starts_with(argument, "--trace-") && + SetCategoryVerbosity(Verbosity_Trace, argument.substr(8))) { - SetLoggingCategories(Logging::LogLevel_TRACE, argument.substr(8)); + // New in Orthanc 1.8.1 } else if (boost::starts_with(argument, "--logdir=")) { diff -r 1661544ea94d -r 0034f855c023 OrthancServer/UnitTestsSources/UnitTestsMain.cpp --- a/OrthancServer/UnitTestsSources/UnitTestsMain.cpp Tue Nov 03 07:19:33 2020 +0100 +++ b/OrthancServer/UnitTestsSources/UnitTestsMain.cpp Tue Nov 03 12:24:50 2020 +0100 @@ -126,6 +126,29 @@ ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("Dcm4Chee"))); ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("SyngoVia"))); ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("AgfaImpax"))); + + ASSERT_STREQ("default", EnumerationToString(StringToVerbosity("default"))); + ASSERT_STREQ("verbose", EnumerationToString(StringToVerbosity("verbose"))); + ASSERT_STREQ("trace", EnumerationToString(StringToVerbosity("trace"))); + ASSERT_THROW(StringToVerbosity("nope"), OrthancException); + + Logging::LogCategory c; + ASSERT_TRUE(Logging::LookupCategory(c, "generic")); ASSERT_EQ(Logging::LogCategory_GENERIC, c); + ASSERT_TRUE(Logging::LookupCategory(c, "plugins")); ASSERT_EQ(Logging::LogCategory_PLUGINS, c); + ASSERT_TRUE(Logging::LookupCategory(c, "rest")); ASSERT_EQ(Logging::LogCategory_REST, c); + ASSERT_TRUE(Logging::LookupCategory(c, "sqlite")); ASSERT_EQ(Logging::LogCategory_SQLITE, c); + ASSERT_TRUE(Logging::LookupCategory(c, "dicom")); ASSERT_EQ(Logging::LogCategory_DICOM, c); + ASSERT_FALSE(Logging::LookupCategory(c, "nope")); + + ASSERT_EQ(5u, Logging::GetCategoriesCount()); + + for (size_t i = 0; i < Logging::GetCategoriesCount(); i++) + { + Logging::LogCategory c; + ASSERT_TRUE(Logging::LookupCategory(c, Logging::GetCategoryName(i))); + } + + ASSERT_THROW(Logging::GetCategoryName(Logging::GetCategoriesCount()), OrthancException); } @@ -509,7 +532,7 @@ { Logging::Initialize(); Toolbox::InitializeGlobalLocale(NULL); - Logging::EnableInfoLevel(true); + SetGlobalVerbosity(Verbosity_Verbose); Toolbox::DetectEndianness(); SystemToolbox::MakeDirectory("UnitTestsResults"); OrthancInitialize();