Coder Social home page Coder Social logo

jgaa / warlib Goto Github PK

View Code? Open in Web Editor NEW
6.0 5.0 0.0 119 KB

A small collection of useful C++ classes targeted for high performance servers.

License: GNU Lesser General Public License v3.0

CMake 7.97% C++ 91.87% C 0.16%
boost-libraries server asio c-plus-plus

warlib's Introduction

warlib

A small collection of useful C++ classes targeted for high performance servers.

Logging

Logging is a pain-point in many C++ projects. My log library was written before boost::log was available, and I must admit that i was a bit disappointed over the complexity of boost:log when it arrived. I have written a handful of logger libraries over the years, and used quite a few in different programing languages. Why so complex? Logging is not all that hard, is it?

WarLog gives you control over what you want to log. You can filter on severity and context, and log-statements that won't be forwarded to any logs are not expanded (the log processing stops after evaluating if the log statement is required).

For example:

  LOG_NOTICE << "If we log at notice level, this line will be processed and logged";

  LOG_DEBUG << "While this will not";

This is significant if some of your log statement contains method calls that are slow (like pulling stack frames, or context data from variables scattered around in memory). Method calls in the log statements are only called if the data is required at the current log-level.

I usually add lots of log statements in my code, much of which I never want to see when things work as expected. Therefore, I have 4 TRACE levels, so that I can log really low-level and frequently called code, and very easily filter it out while still getting lots of details. In a server, like a HTTP server, I may have several layers processing input from the client. I can log the data received over the wire at TRACE level 4, the decompression at level 3, decoding of chunks at level 2, final raw data at level one, and then nicely show what's going on like "Client at 127.0.0.1 sent a GET request regarding "/bla/bla" with headers headers dumped here at debug level. That means that if there ever is a problem with, for example, the chunk-decoding (and be sure - there will be if you wrote it yourself!), it's trivial to deduce from the logs what went wrong. But normally, you will only see the high-level debug messages (and higher).

Log levels:

/*! Log Level */
enum LogLevel {
    /// Fatal error. The application terminates
    LL_FATAL,
    /// Error
    LL_ERROR,
    /// Warning
    LL_WARNING,
    /// Information. Typically program version, internal modules being enabled etc.
    LL_INFO,
    /// Notice. Typically some action that is started or completed.
    LL_NOTICE,
    /// Debug messages. These provides verbose information regarding the processing
    LL_DEBUG,
    /// Trace message
    LL_TRACE1,
    /// Trace message
    LL_TRACE2,
    /// Trace message
    LL_TRACE3,
    /// Trace message
    LL_TRACE4
};

WarLog can also filter on context, based on bits. These are the defined values. You are free to add more yourself in your own code.

enum LogAbout {
    /// General message
    LA_GENERAL  = 0x00000001,
    /// Security
    LA_SECURITY = 0x00000002,
    /// File transfer
    LA_TRANSFER = 0x00000004,
    /// Authentication
    LA_AUTH = 0x00000008,
    /// IO operations (file system)
    LA_IO = 0x00000010,
    /// Network operations (relevant for debug and trace-levels)
    LA_NETWORK = 0x00000020,
    /// Threads (relevant for debug and trace-levels)
    LA_THREADS = 0x00000040,
    /// Inter process commnication (relevant for debug and trace-levels)
    LA_IPC = 0x00000080,
    /// Statistics updates
    LA_STATS = 0x00000100,
    /// Function called and left
    LA_FUNCTION_CALL = 0x00000200
};

WarLog allows you to log at different log-levels and context flags to different logs. A log may be the console, or it may be a file. You can add any number of logs with their own filters. When a log-message is processed, the message traverse trough each logger until all have seen it. There are global variables caching the lowest log-level used by any log. Messages logged at a lower level will be skipped at run-time.

Some examples

TBD

Threadpool

TBD

warlib's People

Contributors

jgaa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

warlib's Issues

Proposed patch for mingw support

Here is a proposed patch to get warlib working on mingw. I have tested with mingw64 currently, but problems with a newer BOOST version are preventing a working build. Some of these patches (the include path fixes, and possibly the FindFirstFile fix) are probably needed on VC builds as well. I don't have VC to test if this patch breaks that build environment.

diff --git a/core/src/WarLog.cpp b/core/src/WarLog.cpp
index 085f164..dfc6eb4 100644
--- a/core/src/WarLog.cpp
+++ b/core/src/WarLog.cpp
@@ -283,11 +283,11 @@ namespace war { namespace log {
     std::ostream& Errno::Explain(std::ostream& out) const
     {
         const char *errstr = "*** Missing error explanation ***";
-#ifdef __GNUC__
+#if defined(__GNUC__) && !defined(__MINGW32__)
         char buf[512] = {};
         strerror_r(GetErrno(), buf, sizeof(buf));
         errstr = buf;
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) || defined(__MINGW32__)
         char buf[512] = {};
         if (strerror_s(buf, sizeof(buf), GetErrno()) == 0)
             errstr = buf;
diff --git a/core/src/win/filecheck.cpp b/core/src/win/filecheck.cpp
index 4eccb7e..c4baa34 100644
--- a/core/src/win/filecheck.cpp
+++ b/core/src/win/filecheck.cpp
@@ -1,7 +1,7 @@
 
 
 #include <windows.h>
-#include "war_filecheck.h"
+#include "warlib/filecheck.h"
 
 
 bool validate_filename_as_safe(const boost::filesystem::path& path)
@@ -11,7 +11,7 @@ bool validate_filename_as_safe(const boost::filesystem::path& path)
     HANDLE h;
 
     // Devices usually have date set to zero
-    h = FindFirstFile(name, &info);
+    h = FindFirstFile(path.string().c_str(), &info);
     if (h != INVALID_HANDLE_VALUE)
     {
         FindClose(h);
diff --git a/core/src/win/minidump.cpp b/core/src/win/minidump.cpp
index f25240b..1b5bcf5 100644
--- a/core/src/win/minidump.cpp
+++ b/core/src/win/minidump.cpp
@@ -10,7 +10,7 @@
 #include <cstdio>
 #include <ctime>
 #include <limits.h>
-#include "win/minidump.h"
+#include "warlib/win/minidump.h"
 
 namespace war {
 

BOOST 1.68.0 Removed boost/context/all.hpp

Newer versions of BOOST have removed the boost/context/all.hpp file. This causes compilation of core/src/WarPipeline.cpp to fail.

I did not see any simple fix mentioned on the announcement from BOOST regarding the removal of this header. I am not sure which boost::context functions are actually in use in the WarPipeline.cpp file. Is it possible that that header file is extraneous and the required boost::context headers will be loaded in other include files?

Deprecated / Removed boost::asio methods

Newer BOOST versions have deprecated and recently removed boost::asio::handler_type and single parameter variant of boost::asio::async_result.

This causes compilation to fail on core/include/warlib/WarPipeline.h

I am not very familiar with boost::asio so I have not been able to generate a successful patch that will replace these functions with a two parameter variant of boost:asio::async_result. The patch below fails because:

warlib/core/include/warlib/WarPipeline.h:139:24: error: use of deleted function 'boost::asio::async_result<CompletionToken, Signature>::async_result(const boost::asio::async_result<CompletionToken, Signature>&) [with CompletionToken = boost::asio::basic_yield_context<boost::asio::executor_binder<void (*)(), boost::asio::executor> >&; Signature = void()]'
  139 |         PostWithTimer({[this, task, milliSeconds, handler_]() {
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  140 |             ExecTask_(task, true);
      |             ~~~~~~~~~~~~~~~~~~~~~~
  141 |             using boost::asio::asio_handler_invoke;
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  142 |             asio_handler_invoke(handler_, &handler_);
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  143 |         }, "Resuming Coroutine"}, milliSeconds);
      |         ~
In file included from /usr/include/boost/asio/detail/handler_type_requirements.hpp:53,
                 from /usr/include/boost/asio/impl/execution_context.hpp:18,
                 from /usr/include/boost/asio/execution_context.hpp:409,
                 from /usr/include/boost/asio/detail/scheduler.hpp:21,
                 from /usr/include/boost/asio/system_context.hpp:19,
                 from /usr/include/boost/asio/impl/system_executor.hpp:22,
                 from /usr/include/boost/asio/system_executor.hpp:129,
                 from /usr/include/boost/asio/associated_executor.hpp:21,
                 from /usr/include/boost/asio.hpp:21,
                 from /home/gotnone/src/warlib/core/include/warlib/WarPipeline.h:14,
                 from /home/gotnone/src/warlib/core/tests/test_tasks.cpp:5:
/usr/include/boost/asio/async_result.hpp:119:3: note: declared here
  119 |   async_result(const async_result&) BOOST_ASIO_DELETED;
      |   ^~~~~~~~~~~~

broken patch:

diff --git a/core/include/warlib/WarPipeline.h b/core/include/warlib/WarPipeline.h
index 451a944..0dc9121 100644
--- a/core/include/warlib/WarPipeline.h
+++ b/core/include/warlib/WarPipeline.h
@@ -70,9 +70,9 @@ public:
      */
     template <typename handlerT>
     void Post(const task_t& task, handlerT&& handler) {
-        typename boost::asio::handler_type<handlerT, void()>::type handler_(
+        typename boost::asio::async_result<handlerT, void()> handler_(
             std::forward<handlerT>(handler));
-        boost::asio::async_result<decltype(handler_)> result(handler_);
+        boost::asio::async_result<decltype(handler_), void()> result(handler_);
         Post({[this, task, handler_]() {
             ExecTask_(task, false);
             using boost::asio::asio_handler_invoke;
@@ -133,9 +133,9 @@ public:
     template <typename handlerT>
     void PostWithTimer(const task_t& task, const std::uint32_t milliSeconds,
                        handlerT&& handler) {
-        typename boost::asio::handler_type<handlerT, void()>::type handler_(
+        typename boost::asio::async_result<handlerT, void()> handler_(
             std::forward<handlerT>(handler));
-        boost::asio::async_result<decltype(handler_)> result(handler_);
+        boost::asio::async_result<decltype(handler_), void()> result(handler_);
         PostWithTimer({[this, task, milliSeconds, handler_]() {
             ExecTask_(task, true);
             using boost::asio::asio_handler_invoke;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.