mirror of https://github.com/gabime/spdlog.git
Merge branch 'master' into custom_flag
commit
955550d3c7
@ -0,0 +1,108 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: DontAlign
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: true
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 140
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp11
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
find . -name "*\.h" -o -name "*\.cpp"|xargs dos2unix
|
|
||||||
find . -name "*\.h" -o -name "*\.cpp"|xargs astyle -n -c -A1
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
# loggers
|
||||||
|
|
||||||
|
Name | License | Lang. | Year | Platform | Compiler | Dependence | URL
|
||||||
|
--- | --- | --- | --- | --- | --- | --- | ---
|
||||||
|
Pantheios | BSD | C++ | 2017 | Windows, Linux, MacOSX | VC++, GCC(3.2+), Intel, Borland, Comeau, Digital Mars, Metrowerks | STLSoft | http://www.pantheios.org/ <br> http://blog.pantheios.org/ <br> https://github.com/synesissoftware/Pantheios <br> http://www.pantheios.org/performance.html
|
||||||
|
Glog | 3-clause BSD| C++| 2017 | Windows, Linux, MacOSX | VC++, GCC, Clang, intel| Google gflags | https://github.com/google/glog
|
||||||
|
G3log | Public Domain | C++11 | 2018 | Windows, Linux, MacOSX, iPhoneOS | VC++, GCC, Clang, MinGW | None | https://github.com/KjellKod/g3log <br> https://github.com/KjellKod/g3sinks <br> https://kjellkod.wordpress.com/2014/08/16/presenting-g3log-the-next-version-of-the-next-generation-of-loggers/ <br> https://kjellkod.wordpress.com/2015/06/30/the-worlds-fastest-logger-vs-g3log/
|
||||||
|
P7 | LGPL | C++, C, C#, Python | 2017 | Windows, Linux | VC++, GCC, Clang, MinGW | None | http://baical.net/p7.html
|
||||||
|
log4cpp | LGPL | C++ | 2017 | Windows, Linux, MacOSX | VC++, GCC, Sun CC, OpenVMS | Boost | http://log4cpp.sourceforge.net/
|
||||||
|
log4cplus | 2-clause BSD or Apache 2 | C++ | 2017 | Windows, Linux, MacOSX, Android | VC++, GCC, Clang | Boost | https://github.com/log4cplus/log4cplus <br> https://sourceforge.net/p/log4cplus/wiki/Home/
|
||||||
|
Easylogging | MIT | C++11 | 2018 | Windows, Linux, MacOSX, iPhoneOS, Android | VC++, GCC, Clang, Intel, MinGW | None | https://github.com/muflihun/easyloggingpp
|
||||||
|
Spdlog | MIT | C++11 | 2018 | Windows, Linux, MacOSX, iPhoneOS, Android(logcat) | VC++, GCC, Clang, MinGW | None, Headers only library | https://github.com/gabime/spdlog <br> https://github.com/fmtlib/fmt
|
||||||
|
Boost.Log v2 | Boost | C++ | 2016 | Windows, Linux, MacOSX, iPhoneOS, Android | VC++, GCC, Clang | Boost | https://github.com/boostorg/log <br> http://www.boost.org/doc/libs/1_66_0/libs/log/doc/html/index.html
|
||||||
|
plog | MPL 2.0 | C++ | 2017 | Windows, Linux, MacOSX, iPhoneOS, Android | gcc, clang, msvc, mingw, mingw-w64, icc, c++builder | None, Headers only library | https://github.com/SergiusTheBest/plog
|
@ -0,0 +1,10 @@
|
|||||||
|
* GLOBAL:
|
||||||
|
FORMAT = "[%datetime]: %levshort %thread %msg"
|
||||||
|
FILENAME = ./logs/easylogging-async.log
|
||||||
|
ENABLED = true
|
||||||
|
TO_FILE = true
|
||||||
|
TO_STANDARD_OUTPUT = false
|
||||||
|
MILLISECONDS_WIDTH = 3
|
||||||
|
PERFORMANCE_TRACKING = false
|
||||||
|
MAX_LOG_FILE_SIZE = 10485760
|
||||||
|
Log_Flush_Threshold = 10485760
|
@ -0,0 +1,10 @@
|
|||||||
|
* GLOBAL:
|
||||||
|
FORMAT = "[%datetime]: %levshort %thread %msg"
|
||||||
|
FILENAME = ./logs/easylogging-mt.log
|
||||||
|
ENABLED = true
|
||||||
|
TO_FILE = true
|
||||||
|
TO_STANDARD_OUTPUT = false
|
||||||
|
MILLISECONDS_WIDTH = 3
|
||||||
|
PERFORMANCE_TRACKING = false
|
||||||
|
MAX_LOG_FILE_SIZE = 10485760
|
||||||
|
Log_Flush_Threshold = 10485760
|
@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define ELPP_THREAD_SAFE
|
||||||
|
#define ELPP_EXPERIMENTAL_ASYNC
|
||||||
|
#include "easylogging++.cc"
|
||||||
|
#include "easylogging++.h"
|
||||||
|
INITIALIZE_EASYLOGGINGPP
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int thread_count = 10;
|
||||||
|
if (argc > 1)
|
||||||
|
thread_count = atoi(argv[1]);
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
// Load configuration from file
|
||||||
|
el::Configurations conf("easyl-async.conf");
|
||||||
|
el::Loggers::reconfigureLogger("default", conf);
|
||||||
|
|
||||||
|
std::atomic<int> msg_counter{0};
|
||||||
|
vector<thread> threads;
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int t = 0; t < thread_count; ++t)
|
||||||
|
{
|
||||||
|
threads.push_back(std::thread([&]() {
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int counter = ++msg_counter;
|
||||||
|
if (counter > howmany)
|
||||||
|
break;
|
||||||
|
LOG(INFO) << "easylog message #" << counter << ": This is some text for your pleasure";
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &t : threads)
|
||||||
|
{
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Threads: " << thread_count << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "g3log/g3log.hpp"
|
||||||
|
#include "g3log/logworker.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
template<typename T>
|
||||||
|
std::string format(const T &value);
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
int thread_count = 10;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
thread_count = atoi(argv[1]);
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
auto worker = g3::LogWorker::createLogWorker();
|
||||||
|
auto handle = worker->addDefaultLogger(argv[0], "logs");
|
||||||
|
g3::initializeLogging(worker.get());
|
||||||
|
|
||||||
|
std::atomic<int> msg_counter{0};
|
||||||
|
vector<thread> threads;
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int t = 0; t < thread_count; ++t)
|
||||||
|
{
|
||||||
|
threads.push_back(std::thread([&]() {
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int counter = ++msg_counter;
|
||||||
|
if (counter > howmany)
|
||||||
|
break;
|
||||||
|
LOG(INFO) << "g3log message #" << counter << ": This is some text for your pleasure";
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &t : threads)
|
||||||
|
{
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
cout << "Total: " << howmany << std::endl;
|
||||||
|
cout << "Threads: " << thread_count << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "log4cplus/fileappender.h"
|
||||||
|
#include "log4cplus/helpers/loglog.h"
|
||||||
|
#include "log4cplus/helpers/property.h"
|
||||||
|
#include "log4cplus/layout.h"
|
||||||
|
#include "log4cplus/logger.h"
|
||||||
|
#include "log4cplus/loggingmacros.h"
|
||||||
|
#include "log4cplus/ndc.h"
|
||||||
|
|
||||||
|
using namespace log4cplus;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int thread_count = 10;
|
||||||
|
if (argc > 1)
|
||||||
|
thread_count = std::atoi(argv[1]);
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
log4cplus::initialize();
|
||||||
|
SharedFileAppenderPtr append(new FileAppender(LOG4CPLUS_TEXT("logs/log4cplus-bench-mt.log"), std::ios_base::trunc, true, true));
|
||||||
|
append->setName(LOG4CPLUS_TEXT("File"));
|
||||||
|
|
||||||
|
log4cplus::tstring pattern = LOG4CPLUS_TEXT("%d{%Y-%m-%d %H:%M:%S.%Q}: %p - %m %n");
|
||||||
|
append->setLayout(std::auto_ptr<Layout>(new PatternLayout(pattern)));
|
||||||
|
append->getloc();
|
||||||
|
Logger::getRoot().addAppender(SharedAppenderPtr(append.get()));
|
||||||
|
|
||||||
|
Logger root = Logger::getRoot();
|
||||||
|
|
||||||
|
std::atomic<int> msg_counter{0};
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int t = 0; t < thread_count; ++t)
|
||||||
|
{
|
||||||
|
threads.push_back(std::thread([&]() {
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int counter = ++msg_counter;
|
||||||
|
if (counter > howmany)
|
||||||
|
break;
|
||||||
|
LOG4CPLUS_INFO(root, "log4cplus message #" << counter << ": This is some text for your pleasure");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &t : threads)
|
||||||
|
{
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Threads: " << thread_count << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
log4cplus::Logger::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "log4cplus/fileappender.h"
|
||||||
|
#include "log4cplus/helpers/loglog.h"
|
||||||
|
#include "log4cplus/helpers/property.h"
|
||||||
|
#include "log4cplus/layout.h"
|
||||||
|
#include "log4cplus/logger.h"
|
||||||
|
#include "log4cplus/loggingmacros.h"
|
||||||
|
#include "log4cplus/ndc.h"
|
||||||
|
|
||||||
|
using namespace log4cplus;
|
||||||
|
|
||||||
|
int main(int, char *[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
log4cplus::initialize();
|
||||||
|
SharedFileAppenderPtr append(new FileAppender(LOG4CPLUS_TEXT("logs/log4cplus-bench.log"), std::ios_base::trunc, true, true));
|
||||||
|
append->setName(LOG4CPLUS_TEXT("File"));
|
||||||
|
|
||||||
|
log4cplus::tstring pattern = LOG4CPLUS_TEXT("%d{%Y-%m-%d %H:%M:%S.%Q}: %p - %m %n");
|
||||||
|
append->setLayout(std::auto_ptr<Layout>(new PatternLayout(pattern)));
|
||||||
|
append->getloc();
|
||||||
|
Logger::getRoot().addAppender(SharedAppenderPtr(append.get()));
|
||||||
|
|
||||||
|
Logger root = Logger::getRoot();
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int i = 0; i < howmany; ++i)
|
||||||
|
LOG4CPLUS_INFO(root, "log4cplus message #" << i << ": This is some text for your pleasure");
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
log4cplus::Logger::shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "log4cpp/Appender.hh"
|
||||||
|
#include "log4cpp/BasicLayout.hh"
|
||||||
|
#include "log4cpp/Category.hh"
|
||||||
|
#include "log4cpp/FileAppender.hh"
|
||||||
|
#include "log4cpp/Layout.hh"
|
||||||
|
#include "log4cpp/PatternLayout.hh"
|
||||||
|
#include "log4cpp/Priority.hh"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int thread_count = 10;
|
||||||
|
if (argc > 1)
|
||||||
|
thread_count = std::atoi(argv[1]);
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
log4cpp::Appender *appender = new log4cpp::FileAppender("default", "logs/log4cpp-bench-mt.log");
|
||||||
|
log4cpp::PatternLayout *layout = new log4cpp::PatternLayout();
|
||||||
|
layout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l}: %p - %m %n");
|
||||||
|
appender->setLayout(layout);
|
||||||
|
|
||||||
|
log4cpp::Category &root = log4cpp::Category::getRoot();
|
||||||
|
root.addAppender(appender);
|
||||||
|
root.setPriority(log4cpp::Priority::INFO);
|
||||||
|
|
||||||
|
std::atomic<int> msg_counter{0};
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int t = 0; t < thread_count; ++t)
|
||||||
|
{
|
||||||
|
threads.push_back(std::thread([&]() {
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int counter = ++msg_counter;
|
||||||
|
if (counter > howmany)
|
||||||
|
break;
|
||||||
|
root << log4cpp::Priority::INFO << "log4cpp message #" << counter << ": This is some text for your pleasure";
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &t : threads)
|
||||||
|
{
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Threads: " << thread_count << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
root.shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "log4cpp/Appender.hh"
|
||||||
|
#include "log4cpp/BasicLayout.hh"
|
||||||
|
#include "log4cpp/Category.hh"
|
||||||
|
#include "log4cpp/FileAppender.hh"
|
||||||
|
#include "log4cpp/Layout.hh"
|
||||||
|
#include "log4cpp/PatternLayout.hh"
|
||||||
|
#include "log4cpp/Priority.hh"
|
||||||
|
|
||||||
|
int main(int, char *[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
log4cpp::Appender *appender = new log4cpp::FileAppender("default", "logs/log4cpp-bench.log");
|
||||||
|
log4cpp::PatternLayout *layout = new log4cpp::PatternLayout();
|
||||||
|
layout->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l}: %p - %m %n");
|
||||||
|
appender->setLayout(layout);
|
||||||
|
|
||||||
|
log4cpp::Category &root = log4cpp::Category::getRoot();
|
||||||
|
root.addAppender(appender);
|
||||||
|
root.setPriority(log4cpp::Priority::INFO);
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int i = 0; i < howmany; ++i)
|
||||||
|
root << log4cpp::Priority::INFO << "log4cpp message #" << i << ": This is some text for your pleasure";
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
root.shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
echo "usage: $0 <program>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROG=$1
|
||||||
|
|
||||||
|
if [ ! -x "$PROG" ]; then
|
||||||
|
echo $PROG not found or not executable.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$* &
|
||||||
|
PID=$!
|
||||||
|
|
||||||
|
while `kill -0 $PID 2>/dev/null`; do
|
||||||
|
ps -eo size,pid,user,pcpu,command --sort -size | awk '{ line=1 ; hr=$1/1024 ; printf("%13.2f Mb ",hr); } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | grep -v grep | grep -v $0 | grep $PROG
|
||||||
|
done
|
@ -0,0 +1,94 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "P7_Trace.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int thread_count = 10;
|
||||||
|
if (argc > 1)
|
||||||
|
thread_count = std::atoi(argv[1]);
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
IP7_Trace::hModule module = NULL;
|
||||||
|
|
||||||
|
// create P7 client object
|
||||||
|
std::unique_ptr<IP7_Client, std::function<void(IP7_Client *)>> client(
|
||||||
|
P7_Create_Client(TM("/P7.Pool=1024 /P7.Sink=FileTxt /P7.Dir=logs/p7-bench-mt")), [&](IP7_Client *ptr) {
|
||||||
|
if (ptr)
|
||||||
|
ptr->Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
std::cout << "Can't create IP7_Client" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create P7 trace object 1
|
||||||
|
std::unique_ptr<IP7_Trace, std::function<void(IP7_Trace *)>> trace(
|
||||||
|
P7_Create_Trace(client.get(), TM("Trace channel 1")), [&](IP7_Trace *ptr) {
|
||||||
|
if (ptr)
|
||||||
|
ptr->Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!trace)
|
||||||
|
{
|
||||||
|
std::cout << "Can't create IP7_Trace" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace->Register_Thread(TM("Application"), 0);
|
||||||
|
trace->Register_Module(TM("Main"), &module);
|
||||||
|
|
||||||
|
std::atomic<int> msg_counter{0};
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int t = 0; t < thread_count; ++t)
|
||||||
|
{
|
||||||
|
threads.push_back(std::thread([&]() {
|
||||||
|
trace->Register_Thread(TM("Application"), t + 1);
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int counter = ++msg_counter;
|
||||||
|
if (counter > howmany)
|
||||||
|
break;
|
||||||
|
trace->P7_INFO(module, TM("p7 message #%d: This is some text for your pleasure"), counter);
|
||||||
|
}
|
||||||
|
trace->Register_Thread(TM("Application"), t + 1);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &t : threads)
|
||||||
|
{
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Threads: " << thread_count << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
trace->Unregister_Thread(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "P7_Trace.h"
|
||||||
|
|
||||||
|
int main(int, char *[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
IP7_Trace::hModule module = NULL;
|
||||||
|
|
||||||
|
// create P7 client object
|
||||||
|
std::unique_ptr<IP7_Client, std::function<void(IP7_Client *)>> client(
|
||||||
|
P7_Create_Client(TM("/P7.Pool=1024 /P7.Sink=FileTxt /P7.Dir=logs/p7-bench")), [&](IP7_Client *ptr) {
|
||||||
|
if (ptr)
|
||||||
|
ptr->Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
std::cout << "Can't create IP7_Client" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create P7 trace object 1
|
||||||
|
std::unique_ptr<IP7_Trace, std::function<void(IP7_Trace *)>> trace(
|
||||||
|
P7_Create_Trace(client.get(), TM("Trace channel 1")), [&](IP7_Trace *ptr) {
|
||||||
|
if (ptr)
|
||||||
|
ptr->Release();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!trace)
|
||||||
|
{
|
||||||
|
std::cout << "Can't create IP7_Trace" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace->Register_Thread(TM("Application"), 0);
|
||||||
|
trace->Register_Module(TM("Main"), &module);
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int i = 0; i < howmany; ++i)
|
||||||
|
trace->P7_INFO(module, TM("p7 message #%d: This is some text for your pleasure"), i);
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
trace->Unregister_Thread(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "plog/Log.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int thread_count = 10;
|
||||||
|
if (argc > 1)
|
||||||
|
thread_count = atoi(argv[1]);
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
plog::init(plog::debug, "logs/plog-bench-mt.log");
|
||||||
|
|
||||||
|
std::atomic<int> msg_counter{0};
|
||||||
|
vector<thread> threads;
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int t = 0; t < thread_count; ++t)
|
||||||
|
{
|
||||||
|
threads.push_back(std::thread([&]() {
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int counter = ++msg_counter;
|
||||||
|
if (counter > howmany)
|
||||||
|
break;
|
||||||
|
LOG_INFO << "plog message #" << counter << ": This is some text for your pleasure";
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &t : threads)
|
||||||
|
{
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Threads: " << thread_count << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "plog/Log.h"
|
||||||
|
|
||||||
|
int main(int, char *[])
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
using clock = steady_clock;
|
||||||
|
|
||||||
|
int howmany = 1000000;
|
||||||
|
|
||||||
|
plog::init(plog::debug, "logs/plog-bench.log");
|
||||||
|
|
||||||
|
auto start = clock::now();
|
||||||
|
for (int i = 0; i < howmany; ++i)
|
||||||
|
LOG_INFO << "plog message #" << i << ": This is some text for your pleasure";
|
||||||
|
|
||||||
|
duration<float> delta = clock::now() - start;
|
||||||
|
float deltaf = delta.count();
|
||||||
|
auto rate = howmany / deltaf;
|
||||||
|
|
||||||
|
std::cout << "Total: " << howmany << std::endl;
|
||||||
|
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
|
||||||
|
std::cout << "Rate = " << rate << "/sec" << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
../example.cpp
|
|
@ -0,0 +1,157 @@
|
|||||||
|
//
|
||||||
|
// Copyright(c) 2015 Gabi Melman.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// spdlog usage example
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#define SPDLOG_TRACE_ON
|
||||||
|
#define SPDLOG_DEBUG_ON
|
||||||
|
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
void async_example();
|
||||||
|
void syslog_example();
|
||||||
|
void android_example();
|
||||||
|
void user_defined_example();
|
||||||
|
void err_handler_example();
|
||||||
|
|
||||||
|
namespace spd = spdlog;
|
||||||
|
int main(int, char *[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Console logger with color
|
||||||
|
auto console = spd::stdout_color_mt("console");
|
||||||
|
console->info("Welcome to spdlog!");
|
||||||
|
console->error("Some error message with arg{}..", 1);
|
||||||
|
|
||||||
|
// Formatting examples
|
||||||
|
console->warn("Easy padding in numbers like {:08d}", 12);
|
||||||
|
console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
|
||||||
|
console->info("Support for floats {:03.2f}", 1.23456);
|
||||||
|
console->info("Positional args are {1} {0}..", "too", "supported");
|
||||||
|
console->info("{:<30}", "left aligned");
|
||||||
|
|
||||||
|
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
|
||||||
|
|
||||||
|
// Create basic file logger (not rotated)
|
||||||
|
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic-log.txt");
|
||||||
|
my_logger->info("Some log message");
|
||||||
|
|
||||||
|
// Create a file rotating logger with 5mb size max and 3 rotated files
|
||||||
|
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
rotating_logger->info("{} * {} equals {:>10}", i, i, i * i);
|
||||||
|
|
||||||
|
// Create a daily logger - a new file is created every day on 2:30am
|
||||||
|
auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
|
||||||
|
// trigger flush if the log severity is error or higher
|
||||||
|
daily_logger->flush_on(spd::level::err);
|
||||||
|
daily_logger->info(123.44);
|
||||||
|
|
||||||
|
// Customize msg format for all messages
|
||||||
|
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
|
||||||
|
rotating_logger->info("This is another message with custom format");
|
||||||
|
|
||||||
|
// Runtime log levels
|
||||||
|
spd::set_level(spd::level::info); // Set global log level to info
|
||||||
|
console->debug("This message should not be displayed!");
|
||||||
|
console->set_level(spd::level::debug); // Set specific logger's log level
|
||||||
|
console->debug("This message should be displayed..");
|
||||||
|
|
||||||
|
// Compile time log levels
|
||||||
|
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
|
||||||
|
SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
|
||||||
|
SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
|
||||||
|
|
||||||
|
// Asynchronous logging is very fast..
|
||||||
|
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
|
||||||
|
async_example();
|
||||||
|
|
||||||
|
// syslog example. linux/osx only
|
||||||
|
syslog_example();
|
||||||
|
|
||||||
|
// android example. compile with NDK
|
||||||
|
android_example();
|
||||||
|
|
||||||
|
// Log user-defined types example
|
||||||
|
user_defined_example();
|
||||||
|
|
||||||
|
// Change default log error handler
|
||||||
|
err_handler_example();
|
||||||
|
|
||||||
|
// Apply a function on all registered loggers
|
||||||
|
spd::apply_all([&](std::shared_ptr<spdlog::logger> l) { l->info("End of example."); });
|
||||||
|
|
||||||
|
// Release and close all loggers
|
||||||
|
spdlog::drop_all();
|
||||||
|
}
|
||||||
|
// Exceptions will only be thrown upon failed logger or sink construction (not during logging)
|
||||||
|
catch (const spd::spdlog_ex &ex)
|
||||||
|
{
|
||||||
|
std::cout << "Log init failed: " << ex.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void async_example()
|
||||||
|
{
|
||||||
|
size_t q_size = 4096; // queue size must be power of 2
|
||||||
|
spdlog::set_async_mode(q_size);
|
||||||
|
auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
async_file->info("Async message #{}", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// syslog example (linux/osx/freebsd)
|
||||||
|
void syslog_example()
|
||||||
|
{
|
||||||
|
#ifdef SPDLOG_ENABLE_SYSLOG
|
||||||
|
std::string ident = "spdlog-example";
|
||||||
|
auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
|
||||||
|
syslog_logger->warn("This is warning that will end up in syslog.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Android example
|
||||||
|
void android_example()
|
||||||
|
{
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
std::string tag = "spdlog-android";
|
||||||
|
auto android_logger = spd::android_logger("android", tag);
|
||||||
|
android_logger->critical("Use \"adb shell logcat\" to view this message.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// user defined types logging by implementing operator<<
|
||||||
|
struct my_type
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
template<typename OStream>
|
||||||
|
friend OStream &operator<<(OStream &os, const my_type &c)
|
||||||
|
{
|
||||||
|
return os << "[my_type i=" << c.i << "]";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "spdlog/fmt/ostr.h" // must be included
|
||||||
|
void user_defined_example()
|
||||||
|
{
|
||||||
|
spd::get("console")->info("user defined type: {}", my_type{14});
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// custom error handler
|
||||||
|
//
|
||||||
|
void err_handler_example()
|
||||||
|
{
|
||||||
|
// can be set globaly or per logger(logger->set_error_handler(..))
|
||||||
|
spdlog::set_error_handler([](const std::string &msg) { std::cerr << "my err handler: " << msg << std::endl; });
|
||||||
|
spd::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3);
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo -n "Running dos2unix "
|
||||||
|
find . -name "*\.h" -o -name "*\.cpp"|xargs -I {} sh -c "dos2unix '{}' 2>/dev/null; echo -n '.'"
|
||||||
|
echo
|
||||||
|
echo -n "Running clang-format "
|
||||||
|
find . -name "*\.h" -o -name "*\.cpp"|xargs -I {} sh -c "clang-format -i {}; echo -n '.'"
|
||||||
|
echo
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
Please put here your contribs. Popular contribs will be moved to main tree after stablization
|
@ -0,0 +1 @@
|
|||||||
|
|
@ -0,0 +1,161 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../details/file_helper.h"
|
||||||
|
#include "../../details/null_mutex.h"
|
||||||
|
#include "../../fmt/fmt.h"
|
||||||
|
#include "../../sinks/base_sink.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <ctime>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Example for spdlog.h
|
||||||
|
//
|
||||||
|
// Create a file logger which creates new files with a specified time step and fixed file size:
|
||||||
|
//
|
||||||
|
// std::shared_ptr<logger> step_logger_mt(const std::string &logger_name, const filename_t &filename, unsigned seconds = 60, const filename_t &tmp_ext = ".tmp", unsigned max_file_size = std::numeric_limits<unsigned>::max());
|
||||||
|
// std::shared_ptr<logger> step_logger_st(const std::string &logger_name, const filename_t &filename, unsigned seconds = 60, const filename_t &tmp_ext = ".tmp", unsigned max_file_size = std::numeric_limits<unsigned>::max();;
|
||||||
|
|
||||||
|
// Example for spdlog_impl.h
|
||||||
|
// Create a file logger that creates new files with a specified increment
|
||||||
|
// inline std::shared_ptr<spdlog::logger> spdlog::step_logger_mt(
|
||||||
|
// const std::string &logger_name, const filename_t &filename_fmt, unsigned seconds, const filename_t &tmp_ext, unsigned max_file_size)
|
||||||
|
// {
|
||||||
|
// return create<spdlog::sinks::step_file_sink_mt>(logger_name, filename_fmt, seconds, tmp_ext, max_file_size);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// inline std::shared_ptr<spdlog::logger> spdlog::step_logger_st(
|
||||||
|
// const std::string &logger_name, const filename_t &filename_fmt, unsigned seconds, const filename_t &tmp_ext, unsigned max_file_size)
|
||||||
|
// {
|
||||||
|
// return create<spdlog::sinks::step_file_sink_st>(logger_name, filename_fmt, seconds, tmp_ext, max_file_size);
|
||||||
|
// }
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace sinks {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default generator of step log file names.
|
||||||
|
*/
|
||||||
|
struct default_step_file_name_calculator
|
||||||
|
{
|
||||||
|
// Create filename for the form filename_YYYY-MM-DD_hh-mm-ss.ext
|
||||||
|
static std::tuple<filename_t, filename_t> calc_filename(const filename_t &filename, const filename_t &tmp_ext)
|
||||||
|
{
|
||||||
|
std::tm tm = spdlog::details::os::localtime();
|
||||||
|
filename_t basename, ext;
|
||||||
|
std::tie(basename, ext) = details::file_helper::split_by_extenstion(filename);
|
||||||
|
std::conditional<std::is_same<filename_t::value_type, char>::value, fmt::MemoryWriter, fmt::WMemoryWriter>::type w;
|
||||||
|
w.write(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}-{:02d}{}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||||
|
tm.tm_hour, tm.tm_min, tm.tm_sec, tmp_ext);
|
||||||
|
return std::make_tuple(w.str(), ext);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rotating file sink based on size and a specified time step
|
||||||
|
*/
|
||||||
|
template<class Mutex, class FileNameCalc = default_step_file_name_calculator>
|
||||||
|
class step_file_sink SPDLOG_FINAL : public base_sink<Mutex>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
step_file_sink(filename_t base_filename, unsigned step_seconds, filename_t tmp_ext, unsigned max_size)
|
||||||
|
: _base_filename(std::move(base_filename))
|
||||||
|
, _tmp_ext(std::move(tmp_ext))
|
||||||
|
, _step_seconds(step_seconds)
|
||||||
|
, _max_size(max_size)
|
||||||
|
{
|
||||||
|
if (step_seconds == 0)
|
||||||
|
{
|
||||||
|
throw spdlog_ex("step_file_sink: Invalid time step in ctor");
|
||||||
|
}
|
||||||
|
if (max_size == 0)
|
||||||
|
{
|
||||||
|
throw spdlog_ex("step_file_sink: Invalid max log size in ctor");
|
||||||
|
}
|
||||||
|
|
||||||
|
_tp = _next_tp();
|
||||||
|
std::tie(_current_filename, _ext) = FileNameCalc::calc_filename(_base_filename, _tmp_ext);
|
||||||
|
|
||||||
|
if (_tmp_ext == _ext)
|
||||||
|
{
|
||||||
|
throw spdlog_ex("step_file_sink: The temporary extension matches the specified in ctor");
|
||||||
|
}
|
||||||
|
|
||||||
|
_file_helper.open(_current_filename);
|
||||||
|
_current_size = _file_helper.size(); // expensive. called only once
|
||||||
|
}
|
||||||
|
|
||||||
|
~step_file_sink()
|
||||||
|
{
|
||||||
|
using details::os::filename_to_str;
|
||||||
|
|
||||||
|
filename_t src =_current_filename, target;
|
||||||
|
std::tie(target, std::ignore) = details::file_helper::split_by_extenstion(src);
|
||||||
|
target += _ext;
|
||||||
|
|
||||||
|
details::os::rename(src, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _sink_it(const details::log_msg &msg) override
|
||||||
|
{
|
||||||
|
_current_size += msg.formatted.size();
|
||||||
|
if (std::chrono::system_clock::now() >= _tp || _current_size > _max_size)
|
||||||
|
{
|
||||||
|
close_current_file();
|
||||||
|
|
||||||
|
std::tie(_current_filename, std::ignore) = FileNameCalc::calc_filename(_base_filename, _tmp_ext);
|
||||||
|
_file_helper.open(_current_filename);
|
||||||
|
_tp = _next_tp();
|
||||||
|
_current_size = msg.formatted.size();
|
||||||
|
}
|
||||||
|
_file_helper.write(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _flush() override
|
||||||
|
{
|
||||||
|
_file_helper.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::chrono::system_clock::time_point _next_tp()
|
||||||
|
{
|
||||||
|
return std::chrono::system_clock::now() + _step_seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_current_file()
|
||||||
|
{
|
||||||
|
using details::os::filename_to_str;
|
||||||
|
|
||||||
|
filename_t src =_current_filename, target;
|
||||||
|
std::tie(target, std::ignore) = details::file_helper::split_by_extenstion(src);
|
||||||
|
target += _ext;
|
||||||
|
|
||||||
|
if (details::file_helper::file_exists(src) && details::os::rename(src, target) != 0)
|
||||||
|
{
|
||||||
|
throw spdlog_ex("step_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename_t _base_filename;
|
||||||
|
const filename_t _tmp_ext;
|
||||||
|
const std::chrono::seconds _step_seconds;
|
||||||
|
const unsigned _max_size;
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point _tp;
|
||||||
|
filename_t _current_filename;
|
||||||
|
filename_t _ext;
|
||||||
|
unsigned _current_size;
|
||||||
|
|
||||||
|
details::file_helper _file_helper;
|
||||||
|
};
|
||||||
|
|
||||||
|
using step_file_sink_mt = step_file_sink<std::mutex>;
|
||||||
|
using step_file_sink_st = step_file_sink<details::null_mutex>;
|
||||||
|
|
||||||
|
} // namespace sinks
|
||||||
|
} // namespace spdlog
|
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "catch.hpp"
|
||||||
|
#include "utils.h"
|
||||||
|
#include <chrono>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <exception>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <chrono>
|
#include <string>
|
||||||
#include <exception>
|
|
||||||
#include "catch.hpp"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#define SPDLOG_TRACE_ON
|
#define SPDLOG_TRACE_ON
|
||||||
#define SPDLOG_DEBUG_ON
|
#define SPDLOG_DEBUG_ON
|
||||||
|
|
||||||
#include "../include/spdlog/spdlog.h"
|
|
||||||
#include "../include/spdlog/sinks/null_sink.h"
|
#include "../include/spdlog/sinks/null_sink.h"
|
||||||
#include "../include/spdlog/sinks/ostream_sink.h"
|
#include "../include/spdlog/sinks/ostream_sink.h"
|
||||||
|
#include "../include/spdlog/spdlog.h"
|
||||||
|
Loading…
Reference in New Issue