├── .gitignore ├── DNScewl ├── LICENSE ├── Libraries ├── Makefile ├── README.md ├── includes ├── CLI11 │ └── CLI11.hpp └── spdlog │ ├── async.h │ ├── async_logger-inl.h │ ├── async_logger.h │ ├── common-inl.h │ ├── common.h │ ├── details │ ├── backtracer-inl.h │ ├── backtracer.h │ ├── circular_q.h │ ├── console_globals.h │ ├── file_helper-inl.h │ ├── file_helper.h │ ├── fmt_helper.h │ ├── log_msg-inl.h │ ├── log_msg.h │ ├── log_msg_buffer.h │ ├── mpmc_blocking_q.h │ ├── null_mutex.h │ ├── os-inl.h │ ├── os.h │ ├── pattern_formatter-inl.h │ ├── pattern_formatter.h │ ├── periodic_worker-inl.h │ ├── periodic_worker.h │ ├── registry-inl.h │ ├── registry.h │ ├── synchronous_factory.h │ ├── thread_pool-inl.h │ └── thread_pool.h │ ├── fmt │ ├── bin_to_hex.h │ ├── bundled │ │ ├── LICENSE.rst │ │ ├── chrono.h │ │ ├── color.h │ │ ├── compile.h │ │ ├── core.h │ │ ├── format-inl.h │ │ ├── format.h │ │ ├── locale.h │ │ ├── ostream.h │ │ ├── posix.h │ │ ├── printf.h │ │ ├── ranges.h │ │ └── safe-duration-cast.h │ ├── fmt.h │ └── ostr.h │ ├── formatter.h │ ├── logger-inl.h │ ├── logger.h │ ├── sinks │ ├── android_sink.h │ ├── ansicolor_sink-inl.h │ ├── ansicolor_sink.h │ ├── base_sink-inl.h │ ├── base_sink.h │ ├── basic_file_sink-inl.h │ ├── basic_file_sink.h │ ├── daily_file_sink.h │ ├── dist_sink.h │ ├── dup_filter_sink.h │ ├── msvc_sink.h │ ├── null_sink.h │ ├── ostream_sink.h │ ├── rotating_file_sink-inl.h │ ├── rotating_file_sink.h │ ├── sink-inl.h │ ├── sink.h │ ├── stdout_color_sinks-inl.h │ ├── stdout_color_sinks.h │ ├── stdout_sinks-inl.h │ ├── stdout_sinks.h │ ├── syslog_sink.h │ ├── systemd_sink.h │ ├── wincolor_sink-inl.h │ └── wincolor_sink.h │ ├── spdlog-inl.h │ ├── spdlog.h │ ├── tweakme.h │ └── version.h ├── input_files ├── appendfile.txt ├── excludefile.txt ├── extension_file.txt ├── set_list.txt └── target_list.txt ├── main.cpp ├── main.o └── sets ├── aws-zones.txt └── non-production-hosts.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /DNScewl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingo/DNSCewl/42bcd521af3285a1cca32753104ee213d18dc9cb/DNScewl -------------------------------------------------------------------------------- /Libraries: -------------------------------------------------------------------------------- 1 | https://github.com/gabime/spdlog 2 | https://github.com/CLIUtils/CLI11 -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | INCLUDES =-I./includes 4 | 5 | LIBINCLUDES =-L./includes -Lbuild/includes 6 | 7 | INC = $(INCLUDES) $(LIBINCLUDES) 8 | CFLAGS=-std=c++11 -lpthread 9 | 10 | OBJS = 11 | 12 | LIBS = 13 | 14 | 15 | DNScewl: main.o 16 | $(CC) $(CFLAGS) $(INC) main.o $(OBJS) $(LIBS) -o $@ 17 | 18 | main.o: main.cpp $(OBJS) 19 | $(CC) $(CFLAGS) $(INC) -c main.cpp 20 | 21 | clean: 22 | rm -f *.o *~ DNScewl 23 | rm -f *.out 24 | rm -f DNScewl -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DNSCewl 2 | [![License](https://img.shields.io/badge/license-GPL3-_red.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html) [![Twitter](https://img.shields.io/badge/twitter-@codingo__-blue.svg)](https://twitter.com/codingo_) 3 | 4 | A DNS Bruteforcing Wordlist Generator. 5 | 6 | | Argument | Description | 7 | |------------|-----------------------------------------------------------------------| 8 | | (stdin) | Specify a list of targets | 9 | | -t | Specify a single target. | 10 | | -tL | Specify a list of targets. | 11 | | -sL | Specify a list of sets to substitue with | 12 | | -eL | Specify a list of targets to exclude | 13 | | -eX | Specify a list of domain extensions to substitute with | 14 | | -a | Specify a file of words to append to a host | 15 | | -p | Specify a file of words to prepend to a host | 16 | | -v | If set then verbose output will be displayed in the terminal | 17 | | -i | If set, original domains (from source files) are included in the output. | 18 | | --range | Set a higher range for integer permutations. | 19 | | --subs | If set then only subdomains will be generated. | 20 | | --no-color | If set then any foreground or background colours will be stripped out | 21 | | --limit | Specify a fixed word limit to output. | 22 | | --level | Specify the level of results to output. | 23 | | --no-repeats | Prevent repeated structures such as one.one.com | 24 | 25 | # Level 26 | There are multiple levels of changes that can be performed, specified by "-level". A level of "1" or above modifies the results to use a `-` as well as everything else. A level of 0 wouldn't use `-`. Level defaults to level 1. 27 | 28 | At level 2 integer substituions start to take place, using a set range. 29 | 30 | # Append 31 | Append works by adding a new subdomain, as well as the word with a `-` and without (unless level is 0). So, for example: 32 | 33 | A target list of: 34 | ``` 35 | example.com 36 | help.example.com 37 | ``` 38 | 39 | With an append list of: 40 | ``` 41 | dev 42 | test 43 | ``` 44 | 45 | With command line as: 46 | 47 | ``` 48 | DNSCewl -tL targets.txt -a append.txt 49 | ``` 50 | 51 | Would provide the output: 52 | 53 | ``` 54 | example-dev.com 55 | example-test.com 56 | help-dev.example.com 57 | help-test.example.com 58 | example.dev.com 59 | example.test.com 60 | help.dev.example.com 61 | help.test.example.com 62 | ``` 63 | 64 | If the flag `--subs` was passed then this would limit results to new subdomains only, and output the following: 65 | 66 | ``` 67 | dev.example.com 68 | devhelp.example.com 69 | dev-help.example.com 70 | dev.help.example.com 71 | test.example.com 72 | testhelp.example.com 73 | test-help.example.com 74 | test.help.example.com 75 | ``` 76 | 77 | # Prepend 78 | 79 | Prepend is the same as append, but at the beginning of a domain (or subdomain). 80 | 81 | Using as: 82 | 83 | ``` 84 | DNSCewl -tL targets.txt -p append.txt 85 | ``` 86 | 87 | Would result in: 88 | 89 | ``` 90 | devexample.com 91 | dev-example.com 92 | dev.example.com 93 | devhelp.example.com 94 | dev-help.example.com 95 | dev.help.example.com 96 | testexample.com 97 | test-example.com 98 | test.example.com 99 | testhelp.example.com 100 | test-help.example.com 101 | test.help.example.com 102 | ``` 103 | 104 | # Level Usage Example 105 | If level 1 was spefied, results with `-` wouldn't be used. For example: 106 | 107 | ``` 108 | DNSCewl -tL targets.txt -p append.txt --level=0 109 | ``` 110 | 111 | Would result in: 112 | 113 | ``` 114 | devexample.com 115 | dev.example.com 116 | devhelp.example.com 117 | dev.help.example.com 118 | testexample.com 119 | test.example.com 120 | testhelp.example.com 121 | test-help.example.com 122 | test.help.example.com 123 | ``` 124 | 125 | # Subs Usage Example 126 | Subs limits results to subdomains only. For example: 127 | 128 | 129 | ``` 130 | DNSCewl -tL targets.txt -p append.txt --level=0 --subs 131 | ``` 132 | 133 | Would result in: 134 | 135 | ``` 136 | dev.example.com 137 | dev.help.example.com 138 | test.example.com 139 | test-help.example.com 140 | test.help.example.com 141 | ``` 142 | 143 | # No repeats example 144 | No repeats prevents the same term being used twice in a domain. 145 | 146 | For example, using `test.example.com` with an prepended list of: 147 | 148 | ``` 149 | test 150 | ``` 151 | 152 | With the following: 153 | 154 | ``` 155 | DNSCewl -tL targets.txt -p append.txt --no-repeats 156 | ``` 157 | 158 | Would result in: 159 | 160 | ``` 161 | test.example.com 162 | test.testexample.com 163 | ``` 164 | 165 | Note that test.test.example.com isn't included, as it's a repeated subdomain. It's important to note that test.testexample.com is still possible here, as --no-repeats shouldn't prevent a subdomain and a top level domain from repeating. 166 | 167 | # Set List (-sL) Example 168 | A set list is a series of words to perform a replacement on when one word in a set is discovered. 169 | 170 | For example, an input of: 171 | 172 | ``` 173 | one.example.com 174 | b.example.com 175 | ``` 176 | 177 | When provided a set list of: 178 | 179 | ``` 180 | one 181 | two 182 | three 183 | ``` 184 | 185 | Would output: 186 | 187 | ``` 188 | two.example.com 189 | three.example.com 190 | ``` 191 | 192 | # Include originals (-i) 193 | If set than the original domains, from source lists are included in outputted results. If not then they will be excluded. 194 | 195 | # Range Example 196 | By default if level=2 is set then any integers in a domain would be incremented and decremented by 100. For example, 197 | 198 | ``` 199 | 101.example.com 200 | ``` 201 | 202 | Would generate domains from 1.example.com to 200.example.com as output. 203 | 204 | Range allows you to override this setting. By default range will adjust to be both negative and positive. For example: 205 | 206 | ``` 207 | --range=10 208 | ``` 209 | Would generate domians from 91.example.com to 111.example.com. You can however specify + or - on range. So for example, 210 | 211 | ``` 212 | --range=+10 213 | ``` 214 | 215 | Would only generate domains from 101.example.com to 111.example.com as our output. 216 | 217 | # Domain Extensions (-eX) 218 | Takes a list of domain extensions and replaces extensions on final results with them. 219 | 220 | For example, 221 | 222 | ``` 223 | example.com 224 | sub.example.com 225 | ``` 226 | 227 | When combined with a list of extentions that includes: 228 | 229 | ``` 230 | .com.au 231 | .co.uk 232 | ``` 233 | 234 | Would result in a list of domains: 235 | 236 | ``` 237 | example.com.au 238 | example.co.uk 239 | sub.example.com.au 240 | sub.example.co.uk 241 | ``` 242 | -------------------------------------------------------------------------------- /includes/spdlog/async.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | // 7 | // Async logging using global thread pool 8 | // All loggers created here share same global thread pool. 9 | // Each log message is pushed to a queue along withe a shared pointer to the 10 | // logger. 11 | // If a logger deleted while having pending messages in the queue, it's actual 12 | // destruction will defer 13 | // until all its messages are processed by the thread pool. 14 | // This is because each message in the queue holds a shared_ptr to the 15 | // originating logger. 16 | 17 | #include "spdlog/async_logger.h" 18 | #include "spdlog/details/registry.h" 19 | #include "spdlog/details/thread_pool.h" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace spdlog { 26 | 27 | namespace details { 28 | static const size_t default_async_q_size = 8192; 29 | } 30 | 31 | // async logger factory - creates async loggers backed with thread pool. 32 | // if a global thread pool doesn't already exist, create it with default queue 33 | // size of 8192 items and single thread. 34 | template 35 | struct async_factory_impl 36 | { 37 | template 38 | static std::shared_ptr create(std::string logger_name, SinkArgs &&... args) 39 | { 40 | auto ®istry_inst = details::registry::instance(); 41 | 42 | // create global thread pool if not already exists.. 43 | 44 | auto &mutex = registry_inst.tp_mutex(); 45 | std::lock_guard tp_lock(mutex); 46 | auto tp = registry_inst.get_tp(); 47 | if (tp == nullptr) 48 | { 49 | tp = std::make_shared(details::default_async_q_size, 1); 50 | registry_inst.set_tp(tp); 51 | } 52 | 53 | auto sink = std::make_shared(std::forward(args)...); 54 | auto new_logger = std::make_shared(std::move(logger_name), std::move(sink), std::move(tp), OverflowPolicy); 55 | registry_inst.initialize_logger(new_logger); 56 | return new_logger; 57 | } 58 | }; 59 | 60 | using async_factory = async_factory_impl; 61 | using async_factory_nonblock = async_factory_impl; 62 | 63 | template 64 | inline std::shared_ptr create_async(std::string logger_name, SinkArgs &&... sink_args) 65 | { 66 | return async_factory::create(std::move(logger_name), std::forward(sink_args)...); 67 | } 68 | 69 | template 70 | inline std::shared_ptr create_async_nb(std::string logger_name, SinkArgs &&... sink_args) 71 | { 72 | return async_factory_nonblock::create(std::move(logger_name), std::forward(sink_args)...); 73 | } 74 | 75 | // set global thread pool. 76 | inline void init_thread_pool(size_t q_size, size_t thread_count, std::function on_thread_start) 77 | { 78 | auto tp = std::make_shared(q_size, thread_count, on_thread_start); 79 | details::registry::instance().set_tp(std::move(tp)); 80 | } 81 | 82 | // set global thread pool. 83 | inline void init_thread_pool(size_t q_size, size_t thread_count) 84 | { 85 | init_thread_pool(q_size, thread_count, [] {}); 86 | } 87 | 88 | // get the global thread pool. 89 | inline std::shared_ptr thread_pool() 90 | { 91 | return details::registry::instance().get_tp(); 92 | } 93 | } // namespace spdlog 94 | -------------------------------------------------------------------------------- /includes/spdlog/async_logger-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/async_logger.h" 8 | #endif 9 | 10 | #include "spdlog/sinks/sink.h" 11 | #include "spdlog/details/thread_pool.h" 12 | 13 | #include 14 | #include 15 | 16 | SPDLOG_INLINE spdlog::async_logger::async_logger( 17 | std::string logger_name, sinks_init_list sinks_list, std::weak_ptr tp, async_overflow_policy overflow_policy) 18 | : async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy) 19 | {} 20 | 21 | SPDLOG_INLINE spdlog::async_logger::async_logger( 22 | std::string logger_name, sink_ptr single_sink, std::weak_ptr tp, async_overflow_policy overflow_policy) 23 | : async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) 24 | {} 25 | 26 | // send the log message to the thread pool 27 | SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg) 28 | { 29 | if (auto pool_ptr = thread_pool_.lock()) 30 | { 31 | pool_ptr->post_log(shared_from_this(), msg, overflow_policy_); 32 | } 33 | else 34 | { 35 | SPDLOG_THROW(spdlog_ex("async log: thread pool doesn't exist anymore")); 36 | } 37 | } 38 | 39 | // send flush request to the thread pool 40 | SPDLOG_INLINE void spdlog::async_logger::flush_() 41 | { 42 | if (auto pool_ptr = thread_pool_.lock()) 43 | { 44 | pool_ptr->post_flush(shared_from_this(), overflow_policy_); 45 | } 46 | else 47 | { 48 | SPDLOG_THROW(spdlog_ex("async flush: thread pool doesn't exist anymore")); 49 | } 50 | } 51 | 52 | // 53 | // backend functions - called from the thread pool to do the actual job 54 | // 55 | SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg &msg) 56 | { 57 | for (auto &sink : sinks_) 58 | { 59 | if (sink->should_log(msg.level)) 60 | { 61 | SPDLOG_TRY 62 | { 63 | sink->log(msg); 64 | } 65 | SPDLOG_LOGGER_CATCH() 66 | } 67 | } 68 | 69 | if (should_flush_(msg)) 70 | { 71 | backend_flush_(); 72 | } 73 | } 74 | 75 | SPDLOG_INLINE void spdlog::async_logger::backend_flush_() 76 | { 77 | for (auto &sink : sinks_) 78 | { 79 | SPDLOG_TRY 80 | { 81 | sink->flush(); 82 | } 83 | SPDLOG_LOGGER_CATCH() 84 | } 85 | } 86 | 87 | SPDLOG_INLINE std::shared_ptr spdlog::async_logger::clone(std::string new_name) 88 | { 89 | auto cloned = std::make_shared(*this); 90 | cloned->name_ = std::move(new_name); 91 | return cloned; 92 | } 93 | -------------------------------------------------------------------------------- /includes/spdlog/async_logger.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | // Fast asynchronous logger. 7 | // Uses pre allocated queue. 8 | // Creates a single back thread to pop messages from the queue and log them. 9 | // 10 | // Upon each log write the logger: 11 | // 1. Checks if its log level is enough to log the message 12 | // 2. Push a new copy of the message to a queue (or block the caller until 13 | // space is available in the queue) 14 | // Upon destruction, logs all remaining messages in the queue before 15 | // destructing.. 16 | 17 | #include "spdlog/logger.h" 18 | 19 | namespace spdlog { 20 | 21 | // Async overflow policy - block by default. 22 | enum class async_overflow_policy 23 | { 24 | block, // Block until message can be enqueued 25 | overrun_oldest // Discard oldest message in the queue if full when trying to 26 | // add new item. 27 | }; 28 | 29 | namespace details { 30 | class thread_pool; 31 | } 32 | 33 | class async_logger final : public std::enable_shared_from_this, public logger 34 | { 35 | friend class details::thread_pool; 36 | 37 | public: 38 | template 39 | async_logger(std::string logger_name, It begin, It end, std::weak_ptr tp, 40 | async_overflow_policy overflow_policy = async_overflow_policy::block) 41 | : logger(std::move(logger_name), begin, end) 42 | , thread_pool_(std::move(tp)) 43 | , overflow_policy_(overflow_policy) 44 | {} 45 | 46 | async_logger(std::string logger_name, sinks_init_list sinks_list, std::weak_ptr tp, 47 | async_overflow_policy overflow_policy = async_overflow_policy::block); 48 | 49 | async_logger(std::string logger_name, sink_ptr single_sink, std::weak_ptr tp, 50 | async_overflow_policy overflow_policy = async_overflow_policy::block); 51 | 52 | std::shared_ptr clone(std::string new_name) override; 53 | 54 | protected: 55 | void sink_it_(const details::log_msg &msg) override; 56 | void flush_() override; 57 | void backend_sink_it_(const details::log_msg &incoming_log_msg); 58 | void backend_flush_(); 59 | 60 | private: 61 | std::weak_ptr thread_pool_; 62 | async_overflow_policy overflow_policy_; 63 | }; 64 | } // namespace spdlog 65 | 66 | #ifdef SPDLOG_HEADER_ONLY 67 | #include "async_logger-inl.h" 68 | #endif 69 | -------------------------------------------------------------------------------- /includes/spdlog/common-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/common.h" 8 | #endif 9 | 10 | namespace spdlog { 11 | namespace level { 12 | static string_view_t level_string_views[] SPDLOG_LEVEL_NAMES; 13 | 14 | static const char *short_level_names[] SPDLOG_SHORT_LEVEL_NAMES; 15 | 16 | SPDLOG_INLINE string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT 17 | { 18 | return level_string_views[l]; 19 | } 20 | 21 | SPDLOG_INLINE const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT 22 | { 23 | return short_level_names[l]; 24 | } 25 | 26 | SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT 27 | { 28 | int level = 0; 29 | for (const auto &level_str : level_string_views) 30 | { 31 | if (level_str == name) 32 | { 33 | return static_cast(level); 34 | } 35 | level++; 36 | } 37 | return level::off; 38 | } 39 | } // namespace level 40 | 41 | SPDLOG_INLINE spdlog_ex::spdlog_ex(std::string msg) 42 | : msg_(std::move(msg)) 43 | {} 44 | 45 | SPDLOG_INLINE spdlog_ex::spdlog_ex(const std::string &msg, int last_errno) 46 | { 47 | memory_buf_t outbuf; 48 | fmt::format_system_error(outbuf, last_errno, msg); 49 | msg_ = fmt::to_string(outbuf); 50 | } 51 | 52 | SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT 53 | { 54 | return msg_.c_str(); 55 | } 56 | 57 | } // namespace spdlog 58 | -------------------------------------------------------------------------------- /includes/spdlog/common.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/tweakme.h" 7 | #include "spdlog/details/null_mutex.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #ifdef _WIN32 19 | #ifndef NOMINMAX 20 | #define NOMINMAX // prevent windows redefining min/max 21 | #endif 22 | 23 | #ifndef WIN32_LEAN_AND_MEAN 24 | #define WIN32_LEAN_AND_MEAN 25 | #endif 26 | 27 | #include 28 | #endif //_WIN32 29 | 30 | #ifdef SPDLOG_COMPILED_LIB 31 | #undef SPDLOG_HEADER_ONLY 32 | #define SPDLOG_INLINE 33 | #else 34 | #define SPDLOG_HEADER_ONLY 35 | #define SPDLOG_INLINE inline 36 | #endif 37 | 38 | #include "spdlog/fmt/fmt.h" 39 | 40 | // visual studio upto 2013 does not support noexcept nor constexpr 41 | #if defined(_MSC_VER) && (_MSC_VER < 1900) 42 | #define SPDLOG_NOEXCEPT throw() 43 | #define SPDLOG_CONSTEXPR 44 | #else 45 | #define SPDLOG_NOEXCEPT noexcept 46 | #define SPDLOG_CONSTEXPR constexpr 47 | #endif 48 | 49 | #if defined(__GNUC__) || defined(__clang__) 50 | #define SPDLOG_DEPRECATED __attribute__((deprecated)) 51 | #elif defined(_MSC_VER) 52 | #define SPDLOG_DEPRECATED __declspec(deprecated) 53 | #else 54 | #define SPDLOG_DEPRECATED 55 | #endif 56 | 57 | // disable thread local on msvc 2013 58 | #ifndef SPDLOG_NO_TLS 59 | #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt) 60 | #define SPDLOG_NO_TLS 1 61 | #endif 62 | #endif 63 | 64 | #ifndef SPDLOG_FUNCTION 65 | #define SPDLOG_FUNCTION __FUNCTION__ 66 | #endif 67 | 68 | #ifdef SPDLOG_NO_EXCEPTIONS 69 | #define SPDLOG_TRY 70 | #define SPDLOG_THROW(ex) \ 71 | do \ 72 | { \ 73 | printf("spdlog fatal error: %s\n", ex.what()); \ 74 | std::abort(); \ 75 | } while (0) 76 | #define SPDLOG_CATCH_ALL() 77 | #else 78 | #define SPDLOG_TRY try 79 | #define SPDLOG_THROW(ex) throw(ex) 80 | #define SPDLOG_CATCH_ALL() catch (...) 81 | #endif 82 | 83 | namespace spdlog { 84 | 85 | class formatter; 86 | 87 | namespace sinks { 88 | class sink; 89 | } 90 | 91 | #if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) 92 | using filename_t = std::wstring; 93 | #define SPDLOG_FILENAME_T(s) L##s 94 | #else 95 | using filename_t = std::string; 96 | #define SPDLOG_FILENAME_T(s) s 97 | #endif 98 | 99 | using log_clock = std::chrono::system_clock; 100 | using sink_ptr = std::shared_ptr; 101 | using sinks_init_list = std::initializer_list; 102 | using err_handler = std::function; 103 | 104 | template 105 | using basic_string_view_t = fmt::basic_string_view; 106 | 107 | using string_view_t = basic_string_view_t; 108 | 109 | using memory_buf_t = fmt::basic_memory_buffer; 110 | 111 | #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT 112 | #ifndef _WIN32 113 | #error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows 114 | #else 115 | using wstring_view_t = basic_string_view_t; 116 | 117 | template 118 | struct is_convertible_to_wstring_view : std::is_convertible 119 | {}; 120 | #endif // _WIN32 121 | #else 122 | template 123 | struct is_convertible_to_wstring_view : std::false_type 124 | {}; 125 | #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT 126 | 127 | #if defined(SPDLOG_NO_ATOMIC_LEVELS) 128 | using level_t = details::null_atomic_int; 129 | #else 130 | using level_t = std::atomic; 131 | #endif 132 | 133 | #define SPDLOG_LEVEL_TRACE 0 134 | #define SPDLOG_LEVEL_DEBUG 1 135 | #define SPDLOG_LEVEL_INFO 2 136 | #define SPDLOG_LEVEL_WARN 3 137 | #define SPDLOG_LEVEL_ERROR 4 138 | #define SPDLOG_LEVEL_CRITICAL 5 139 | #define SPDLOG_LEVEL_OFF 6 140 | 141 | #if !defined(SPDLOG_ACTIVE_LEVEL) 142 | #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO 143 | #endif 144 | 145 | // Log level enum 146 | namespace level { 147 | enum level_enum 148 | { 149 | trace = SPDLOG_LEVEL_TRACE, 150 | debug = SPDLOG_LEVEL_DEBUG, 151 | info = SPDLOG_LEVEL_INFO, 152 | warn = SPDLOG_LEVEL_WARN, 153 | err = SPDLOG_LEVEL_ERROR, 154 | critical = SPDLOG_LEVEL_CRITICAL, 155 | off = SPDLOG_LEVEL_OFF, 156 | }; 157 | 158 | #if !defined(SPDLOG_LEVEL_NAMES) 159 | #define SPDLOG_LEVEL_NAMES \ 160 | { \ 161 | "trace", "debug", "info", "warning", "error", "critical", "off" \ 162 | } 163 | #endif 164 | 165 | #if !defined(SPDLOG_SHORT_LEVEL_NAMES) 166 | 167 | #define SPDLOG_SHORT_LEVEL_NAMES \ 168 | { \ 169 | "T", "D", "I", "W", "E", "C", "O" \ 170 | } 171 | #endif 172 | 173 | string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; 174 | const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; 175 | spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT; 176 | 177 | using level_hasher = std::hash; 178 | } // namespace level 179 | 180 | // 181 | // Color mode used by sinks with color support. 182 | // 183 | enum class color_mode 184 | { 185 | always, 186 | automatic, 187 | never 188 | }; 189 | 190 | // 191 | // Pattern time - specific time getting to use for pattern_formatter. 192 | // local time by default 193 | // 194 | enum class pattern_time_type 195 | { 196 | local, // log localtime 197 | utc // log utc 198 | }; 199 | 200 | // 201 | // Log exception 202 | // 203 | class spdlog_ex : public std::exception 204 | { 205 | public: 206 | explicit spdlog_ex(std::string msg); 207 | spdlog_ex(const std::string &msg, int last_errno); 208 | const char *what() const SPDLOG_NOEXCEPT override; 209 | 210 | private: 211 | std::string msg_; 212 | }; 213 | 214 | struct source_loc 215 | { 216 | SPDLOG_CONSTEXPR source_loc() = default; 217 | SPDLOG_CONSTEXPR source_loc(const char *filename_in, int line_in, const char *funcname_in) 218 | : filename{filename_in} 219 | , line{line_in} 220 | , funcname{funcname_in} 221 | {} 222 | 223 | SPDLOG_CONSTEXPR bool empty() const SPDLOG_NOEXCEPT 224 | { 225 | return line == 0; 226 | } 227 | const char *filename{nullptr}; 228 | int line{0}; 229 | const char *funcname{nullptr}; 230 | }; 231 | 232 | namespace details { 233 | // make_unique support for pre c++14 234 | 235 | #if __cplusplus >= 201402L // C++14 and beyond 236 | using std::make_unique; 237 | #else 238 | template 239 | std::unique_ptr make_unique(Args &&... args) 240 | { 241 | static_assert(!std::is_array::value, "arrays not supported"); 242 | return std::unique_ptr(new T(std::forward(args)...)); 243 | } 244 | #endif 245 | } // namespace details 246 | 247 | } // namespace spdlog 248 | 249 | #ifdef SPDLOG_HEADER_ONLY 250 | #include "common-inl.h" 251 | #endif 252 | -------------------------------------------------------------------------------- /includes/spdlog/details/backtracer-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/details/backtracer.h" 8 | #endif 9 | namespace spdlog { 10 | namespace details { 11 | SPDLOG_INLINE backtracer::backtracer(const backtracer &other) 12 | { 13 | std::lock_guard lock(other.mutex_); 14 | enabled_ = other.enabled(); 15 | messages_ = other.messages_; 16 | } 17 | 18 | SPDLOG_INLINE backtracer::backtracer(backtracer &&other) SPDLOG_NOEXCEPT 19 | { 20 | std::lock_guard lock(other.mutex_); 21 | enabled_ = other.enabled(); 22 | messages_ = std::move(other.messages_); 23 | } 24 | 25 | SPDLOG_INLINE backtracer &backtracer::operator=(backtracer other) 26 | { 27 | std::lock_guard lock(mutex_); 28 | enabled_ = other.enabled(); 29 | messages_ = other.messages_; 30 | return *this; 31 | } 32 | 33 | SPDLOG_INLINE void backtracer::enable(size_t size) 34 | { 35 | std::lock_guard lock{mutex_}; 36 | enabled_.store(true, std::memory_order_relaxed); 37 | messages_ = circular_q{size}; 38 | } 39 | 40 | SPDLOG_INLINE void backtracer::disable() 41 | { 42 | std::lock_guard lock{mutex_}; 43 | enabled_.store(false, std::memory_order_relaxed); 44 | } 45 | 46 | SPDLOG_INLINE bool backtracer::enabled() const 47 | { 48 | return enabled_.load(std::memory_order_relaxed); 49 | } 50 | 51 | SPDLOG_INLINE backtracer::operator bool() const 52 | { 53 | return enabled(); 54 | } 55 | 56 | SPDLOG_INLINE void backtracer::push_back(const log_msg &msg) 57 | { 58 | std::lock_guard lock{mutex_}; 59 | messages_.push_back(log_msg_buffer{msg}); 60 | } 61 | 62 | // pop all items in the q and apply the given fun on each of them. 63 | SPDLOG_INLINE void backtracer::foreach_pop(std::function fun) 64 | { 65 | std::lock_guard lock{mutex_}; 66 | while (!messages_.empty()) 67 | { 68 | log_msg_buffer popped; 69 | messages_.pop_front(popped); 70 | fun(popped); 71 | } 72 | } 73 | } // namespace details 74 | } // namespace spdlog 75 | -------------------------------------------------------------------------------- /includes/spdlog/details/backtracer.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/log_msg_buffer.h" 7 | #include "spdlog/details/circular_q.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // Store log messages in circular buffer. 14 | // Useful for storing debug data in case of error/warning happens. 15 | 16 | namespace spdlog { 17 | namespace details { 18 | class backtracer 19 | { 20 | mutable std::mutex mutex_; 21 | std::atomic enabled_{false}; 22 | circular_q messages_; 23 | 24 | public: 25 | backtracer() = default; 26 | backtracer(const backtracer &other); 27 | 28 | backtracer(backtracer &&other) SPDLOG_NOEXCEPT; 29 | backtracer &operator=(backtracer other); 30 | 31 | void enable(size_t size); 32 | void disable(); 33 | bool enabled() const; 34 | explicit operator bool() const; 35 | void push_back(const log_msg &msg); 36 | 37 | // pop all items in the q and apply the given fun on each of them. 38 | void foreach_pop(std::function fun); 39 | }; 40 | 41 | } // namespace details 42 | } // namespace spdlog 43 | 44 | #ifdef SPDLOG_HEADER_ONLY 45 | #include "backtracer-inl.h" 46 | #endif -------------------------------------------------------------------------------- /includes/spdlog/details/circular_q.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | // cirucal q view of std::vector. 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace spdlog { 10 | namespace details { 11 | template 12 | class circular_q 13 | { 14 | size_t max_items_ = 0; 15 | typename std::vector::size_type head_ = 0; 16 | typename std::vector::size_type tail_ = 0; 17 | size_t overrun_counter_ = 0; 18 | std::vector v_; 19 | 20 | public: 21 | using item_type = T; 22 | 23 | // empty cir 24 | circular_q() = default; 25 | 26 | explicit circular_q(size_t max_items) 27 | : max_items_(max_items + 1) // one item is reserved as marker for full q 28 | , v_(max_items_) 29 | {} 30 | 31 | circular_q(const circular_q &) = default; 32 | circular_q &operator=(const circular_q &) = default; 33 | 34 | // move cannot be default, 35 | // since we need to reset head_, tail_, etc to zero in the moved object 36 | circular_q(circular_q &&other) SPDLOG_NOEXCEPT 37 | { 38 | copy_moveable(std::move(other)); 39 | } 40 | 41 | circular_q &operator=(circular_q &&other) SPDLOG_NOEXCEPT 42 | { 43 | copy_moveable(std::move(other)); 44 | return *this; 45 | } 46 | 47 | // push back, overrun (oldest) item if no room left 48 | void push_back(T &&item) 49 | { 50 | if (max_items_ > 0) 51 | { 52 | v_[tail_] = std::move(item); 53 | tail_ = (tail_ + 1) % max_items_; 54 | 55 | if (tail_ == head_) // overrun last item if full 56 | { 57 | head_ = (head_ + 1) % max_items_; 58 | ++overrun_counter_; 59 | } 60 | } 61 | } 62 | 63 | // Pop item from front. 64 | // If there are no elements in the container, the behavior is undefined. 65 | void pop_front(T &popped_item) 66 | { 67 | if (max_items_ > 0) 68 | { 69 | popped_item = std::move(v_[head_]); 70 | head_ = (head_ + 1) % max_items_; 71 | } 72 | } 73 | 74 | bool empty() const 75 | { 76 | return tail_ == head_; 77 | } 78 | 79 | bool full() const 80 | { 81 | // head is ahead of the tail by 1 82 | return ((tail_ + 1) % max_items_) == head_; 83 | } 84 | 85 | size_t overrun_counter() const 86 | { 87 | return overrun_counter_; 88 | } 89 | 90 | private: 91 | // copy from other&& and reset it to disabled state 92 | void copy_moveable(circular_q &&other) SPDLOG_NOEXCEPT 93 | { 94 | max_items_ = other.max_items_; 95 | head_ = other.head_; 96 | tail_ = other.tail_; 97 | overrun_counter_ = other.overrun_counter_; 98 | v_ = std::move(other.v_); 99 | 100 | // put &&other in disabled, but valid state 101 | other.max_items_ = 0; 102 | other.head_ = other.tail_ = 0; 103 | other.overrun_counter_ = 0; 104 | } 105 | }; 106 | } // namespace details 107 | } // namespace spdlog 108 | -------------------------------------------------------------------------------- /includes/spdlog/details/console_globals.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/null_mutex.h" 7 | #include 8 | 9 | namespace spdlog { 10 | namespace details { 11 | 12 | struct console_mutex 13 | { 14 | using mutex_t = std::mutex; 15 | static mutex_t &mutex() 16 | { 17 | static mutex_t s_mutex; 18 | return s_mutex; 19 | } 20 | }; 21 | 22 | struct console_nullmutex 23 | { 24 | using mutex_t = null_mutex; 25 | static mutex_t &mutex() 26 | { 27 | static mutex_t s_mutex; 28 | return s_mutex; 29 | } 30 | }; 31 | } // namespace details 32 | } // namespace spdlog 33 | -------------------------------------------------------------------------------- /includes/spdlog/details/file_helper-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/details/file_helper.h" 8 | #endif 9 | 10 | #include "spdlog/details/os.h" 11 | #include "spdlog/common.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace spdlog { 21 | namespace details { 22 | 23 | SPDLOG_INLINE file_helper::~file_helper() 24 | { 25 | close(); 26 | } 27 | 28 | SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) 29 | { 30 | close(); 31 | auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab"); 32 | _filename = fname; 33 | for (int tries = 0; tries < open_tries; ++tries) 34 | { 35 | if (!os::fopen_s(&fd_, fname, mode)) 36 | { 37 | return; 38 | } 39 | 40 | details::os::sleep_for_millis(open_interval); 41 | } 42 | 43 | SPDLOG_THROW(spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno)); 44 | } 45 | 46 | SPDLOG_INLINE void file_helper::reopen(bool truncate) 47 | { 48 | if (_filename.empty()) 49 | { 50 | SPDLOG_THROW(spdlog_ex("Failed re opening file - was not opened before")); 51 | } 52 | open(_filename, truncate); 53 | } 54 | 55 | SPDLOG_INLINE void file_helper::flush() 56 | { 57 | std::fflush(fd_); 58 | } 59 | 60 | SPDLOG_INLINE void file_helper::close() 61 | { 62 | if (fd_ != nullptr) 63 | { 64 | std::fclose(fd_); 65 | fd_ = nullptr; 66 | } 67 | } 68 | 69 | SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf) 70 | { 71 | size_t msg_size = buf.size(); 72 | auto data = buf.data(); 73 | if (std::fwrite(data, 1, msg_size, fd_) != msg_size) 74 | { 75 | SPDLOG_THROW(spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno)); 76 | } 77 | } 78 | 79 | SPDLOG_INLINE size_t file_helper::size() const 80 | { 81 | if (fd_ == nullptr) 82 | { 83 | SPDLOG_THROW(spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename))); 84 | } 85 | return os::filesize(fd_); 86 | } 87 | 88 | SPDLOG_INLINE const filename_t &file_helper::filename() const 89 | { 90 | return _filename; 91 | } 92 | 93 | SPDLOG_INLINE bool file_helper::file_exists(const filename_t &fname) 94 | { 95 | return os::file_exists(fname); 96 | } 97 | 98 | // 99 | // return file path and its extension: 100 | // 101 | // "mylog.txt" => ("mylog", ".txt") 102 | // "mylog" => ("mylog", "") 103 | // "mylog." => ("mylog.", "") 104 | // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt") 105 | // 106 | // the starting dot in filenames is ignored (hidden files): 107 | // 108 | // ".mylog" => (".mylog". "") 109 | // "my_folder/.mylog" => ("my_folder/.mylog", "") 110 | // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt") 111 | SPDLOG_INLINE std::tuple file_helper::split_by_extension(const filename_t &fname) 112 | { 113 | auto ext_index = fname.rfind('.'); 114 | 115 | // no valid extension found - return whole path and empty string as 116 | // extension 117 | if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1) 118 | { 119 | return std::make_tuple(fname, filename_t()); 120 | } 121 | 122 | // treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile" 123 | auto folder_index = fname.rfind(details::os::folder_sep); 124 | if (folder_index != filename_t::npos && folder_index >= ext_index - 1) 125 | { 126 | return std::make_tuple(fname, filename_t()); 127 | } 128 | 129 | // finally - return a valid base and extension tuple 130 | return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index)); 131 | } 132 | } // namespace details 133 | } // namespace spdlog 134 | -------------------------------------------------------------------------------- /includes/spdlog/details/file_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/common.h" 7 | #include 8 | 9 | namespace spdlog { 10 | namespace details { 11 | 12 | // Helper class for file sinks. 13 | // When failing to open a file, retry several times(5) with a delay interval(10 ms). 14 | // Throw spdlog_ex exception on errors. 15 | 16 | class file_helper 17 | { 18 | public: 19 | explicit file_helper() = default; 20 | 21 | file_helper(const file_helper &) = delete; 22 | file_helper &operator=(const file_helper &) = delete; 23 | ~file_helper(); 24 | 25 | void open(const filename_t &fname, bool truncate = false); 26 | void reopen(bool truncate); 27 | void flush(); 28 | void close(); 29 | void write(const memory_buf_t &buf); 30 | size_t size() const; 31 | const filename_t &filename() const; 32 | static bool file_exists(const filename_t &fname); 33 | 34 | // 35 | // return file path and its extension: 36 | // 37 | // "mylog.txt" => ("mylog", ".txt") 38 | // "mylog" => ("mylog", "") 39 | // "mylog." => ("mylog.", "") 40 | // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt") 41 | // 42 | // the starting dot in filenames is ignored (hidden files): 43 | // 44 | // ".mylog" => (".mylog". "") 45 | // "my_folder/.mylog" => ("my_folder/.mylog", "") 46 | // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt") 47 | static std::tuple split_by_extension(const filename_t &fname); 48 | 49 | private: 50 | const int open_tries = 5; 51 | const int open_interval = 10; 52 | std::FILE *fd_{nullptr}; 53 | filename_t _filename; 54 | }; 55 | } // namespace details 56 | } // namespace spdlog 57 | 58 | #ifdef SPDLOG_HEADER_ONLY 59 | #include "file_helper-inl.h" 60 | #endif 61 | -------------------------------------------------------------------------------- /includes/spdlog/details/fmt_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include "spdlog/fmt/fmt.h" 8 | #include "spdlog/common.h" 9 | 10 | // Some fmt helpers to efficiently format and pad ints and strings 11 | namespace spdlog { 12 | namespace details { 13 | namespace fmt_helper { 14 | 15 | inline spdlog::string_view_t to_string_view(const memory_buf_t &buf) SPDLOG_NOEXCEPT 16 | { 17 | return spdlog::string_view_t{buf.data(), buf.size()}; 18 | } 19 | 20 | inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest) 21 | { 22 | auto *buf_ptr = view.data(); 23 | if (buf_ptr != nullptr) 24 | { 25 | dest.append(buf_ptr, buf_ptr + view.size()); 26 | } 27 | } 28 | 29 | template 30 | inline void append_int(T n, memory_buf_t &dest) 31 | { 32 | fmt::format_int i(n); 33 | dest.append(i.data(), i.data() + i.size()); 34 | } 35 | 36 | template 37 | inline unsigned count_digits(T n) 38 | { 39 | using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type; 40 | return static_cast(fmt::internal::count_digits(static_cast(n))); 41 | } 42 | 43 | inline void pad2(int n, memory_buf_t &dest) 44 | { 45 | if (n > 99) 46 | { 47 | append_int(n, dest); 48 | } 49 | else if (n > 9) // 10-99 50 | { 51 | dest.push_back(static_cast('0' + n / 10)); 52 | dest.push_back(static_cast('0' + n % 10)); 53 | } 54 | else if (n >= 0) // 0-9 55 | { 56 | dest.push_back('0'); 57 | dest.push_back(static_cast('0' + n)); 58 | } 59 | else // negatives (unlikely, but just in case, let fmt deal with it) 60 | { 61 | fmt::format_to(dest, "{:02}", n); 62 | } 63 | } 64 | 65 | template 66 | inline void pad_uint(T n, unsigned int width, memory_buf_t &dest) 67 | { 68 | static_assert(std::is_unsigned::value, "pad_uint must get unsigned T"); 69 | auto digits = count_digits(n); 70 | if (width > digits) 71 | { 72 | const char *zeroes = "0000000000000000000"; 73 | dest.append(zeroes, zeroes + width - digits); 74 | } 75 | append_int(n, dest); 76 | } 77 | 78 | template 79 | inline void pad3(T n, memory_buf_t &dest) 80 | { 81 | pad_uint(n, 3, dest); 82 | } 83 | 84 | template 85 | inline void pad6(T n, memory_buf_t &dest) 86 | { 87 | pad_uint(n, 6, dest); 88 | } 89 | 90 | template 91 | inline void pad9(T n, memory_buf_t &dest) 92 | { 93 | pad_uint(n, 9, dest); 94 | } 95 | 96 | // return fraction of a second of the given time_point. 97 | // e.g. 98 | // fraction(tp) -> will return the millis part of the second 99 | template 100 | inline ToDuration time_fraction(log_clock::time_point tp) 101 | { 102 | using std::chrono::duration_cast; 103 | using std::chrono::seconds; 104 | auto duration = tp.time_since_epoch(); 105 | auto secs = duration_cast(duration); 106 | return duration_cast(duration) - duration_cast(secs); 107 | } 108 | 109 | } // namespace fmt_helper 110 | } // namespace details 111 | } // namespace spdlog 112 | -------------------------------------------------------------------------------- /includes/spdlog/details/log_msg-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/details/log_msg.h" 8 | #endif 9 | 10 | #include "spdlog/details/os.h" 11 | 12 | namespace spdlog { 13 | namespace details { 14 | 15 | SPDLOG_INLINE log_msg::log_msg(spdlog::source_loc loc, string_view_t logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg) 16 | : logger_name(logger_name) 17 | , level(lvl) 18 | #ifndef SPDLOG_NO_DATETIME 19 | , time(os::now()) 20 | #endif 21 | 22 | #ifndef SPDLOG_NO_THREAD_ID 23 | , thread_id(os::thread_id()) 24 | #endif 25 | , source(loc) 26 | , payload(msg) 27 | {} 28 | 29 | SPDLOG_INLINE log_msg::log_msg(string_view_t logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg) 30 | : log_msg(source_loc{}, logger_name, lvl, msg) 31 | {} 32 | 33 | } // namespace details 34 | } // namespace spdlog 35 | -------------------------------------------------------------------------------- /includes/spdlog/details/log_msg.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/common.h" 7 | #include 8 | 9 | namespace spdlog { 10 | namespace details { 11 | struct log_msg 12 | { 13 | log_msg() = default; 14 | log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg); 15 | log_msg(string_view_t logger_name, level::level_enum lvl, string_view_t msg); 16 | log_msg(const log_msg &other) = default; 17 | 18 | string_view_t logger_name; 19 | level::level_enum level{level::off}; 20 | log_clock::time_point time; 21 | size_t thread_id{0}; 22 | 23 | // wrapping the formatted text with color (updated by pattern_formatter). 24 | mutable size_t color_range_start{0}; 25 | mutable size_t color_range_end{0}; 26 | 27 | source_loc source; 28 | string_view_t payload; 29 | }; 30 | } // namespace details 31 | } // namespace spdlog 32 | 33 | #ifdef SPDLOG_HEADER_ONLY 34 | #include "log_msg-inl.h" 35 | #endif 36 | -------------------------------------------------------------------------------- /includes/spdlog/details/log_msg_buffer.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/log_msg.h" 7 | #include "spdlog/fmt/fmt.h" 8 | 9 | namespace spdlog { 10 | namespace details { 11 | 12 | // extend log_msg with internal buffer to store its payload. 13 | // this is needed since log_msg holds string_views that points to stack data. 14 | 15 | class log_msg_buffer : public log_msg 16 | { 17 | memory_buf_t buffer; 18 | void update_string_views() 19 | { 20 | logger_name = string_view_t{buffer.data(), logger_name.size()}; 21 | payload = string_view_t{logger_name.end(), payload.size()}; 22 | } 23 | 24 | public: 25 | log_msg_buffer() = default; 26 | 27 | explicit log_msg_buffer(const log_msg &orig_msg) 28 | : log_msg{orig_msg} 29 | { 30 | buffer.append(logger_name.begin(), logger_name.end()); 31 | buffer.append(payload.begin(), payload.end()); 32 | update_string_views(); 33 | } 34 | 35 | log_msg_buffer(const log_msg_buffer &other) 36 | : log_msg{other} 37 | { 38 | buffer.append(logger_name.begin(), logger_name.end()); 39 | buffer.append(payload.begin(), payload.end()); 40 | update_string_views(); 41 | } 42 | 43 | log_msg_buffer(log_msg_buffer &&other) 44 | : log_msg{std::move(other)} 45 | , buffer{std::move(other.buffer)} 46 | { 47 | update_string_views(); 48 | } 49 | 50 | log_msg_buffer &operator=(const log_msg_buffer &other) 51 | { 52 | log_msg::operator=(other); 53 | buffer.append(other.buffer.data(), other.buffer.data() + other.buffer.size()); 54 | update_string_views(); 55 | return *this; 56 | } 57 | 58 | log_msg_buffer &operator=(log_msg_buffer &&other) 59 | { 60 | log_msg::operator=(std::move(other)); 61 | buffer = std::move(other.buffer); 62 | update_string_views(); 63 | return *this; 64 | } 65 | }; 66 | 67 | } // namespace details 68 | } // namespace spdlog 69 | -------------------------------------------------------------------------------- /includes/spdlog/details/mpmc_blocking_q.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | // multi producer-multi consumer blocking queue. 7 | // enqueue(..) - will block until room found to put the new message. 8 | // enqueue_nowait(..) - will return immediately with false if no room left in 9 | // the queue. 10 | // dequeue_for(..) - will block until the queue is not empty or timeout have 11 | // passed. 12 | 13 | #include "spdlog/details/circular_q.h" 14 | 15 | #include 16 | #include 17 | 18 | namespace spdlog { 19 | namespace details { 20 | 21 | template 22 | class mpmc_blocking_queue 23 | { 24 | public: 25 | using item_type = T; 26 | explicit mpmc_blocking_queue(size_t max_items) 27 | : q_(max_items) 28 | {} 29 | 30 | #ifndef __MINGW32__ 31 | // try to enqueue and block if no room left 32 | void enqueue(T &&item) 33 | { 34 | { 35 | std::unique_lock lock(queue_mutex_); 36 | pop_cv_.wait(lock, [this] { return !this->q_.full(); }); 37 | q_.push_back(std::move(item)); 38 | } 39 | push_cv_.notify_one(); 40 | } 41 | 42 | // enqueue immediately. overrun oldest message in the queue if no room left. 43 | void enqueue_nowait(T &&item) 44 | { 45 | { 46 | std::unique_lock lock(queue_mutex_); 47 | q_.push_back(std::move(item)); 48 | } 49 | push_cv_.notify_one(); 50 | } 51 | 52 | // try to dequeue item. if no item found. wait upto timeout and try again 53 | // Return true, if succeeded dequeue item, false otherwise 54 | bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) 55 | { 56 | { 57 | std::unique_lock lock(queue_mutex_); 58 | if (!push_cv_.wait_for(lock, wait_duration, [this] { return !this->q_.empty(); })) 59 | { 60 | return false; 61 | } 62 | q_.pop_front(popped_item); 63 | } 64 | pop_cv_.notify_one(); 65 | return true; 66 | } 67 | 68 | #else 69 | // apparently mingw deadlocks if the mutex is released before cv.notify_one(), 70 | // so release the mutex at the very end each function. 71 | 72 | // try to enqueue and block if no room left 73 | void enqueue(T &&item) 74 | { 75 | std::unique_lock lock(queue_mutex_); 76 | pop_cv_.wait(lock, [this] { return !this->q_.full(); }); 77 | q_.push_back(std::move(item)); 78 | push_cv_.notify_one(); 79 | } 80 | 81 | // enqueue immediately. overrun oldest message in the queue if no room left. 82 | void enqueue_nowait(T &&item) 83 | { 84 | std::unique_lock lock(queue_mutex_); 85 | q_.push_back(std::move(item)); 86 | push_cv_.notify_one(); 87 | } 88 | 89 | // try to dequeue item. if no item found. wait upto timeout and try again 90 | // Return true, if succeeded dequeue item, false otherwise 91 | bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) 92 | { 93 | std::unique_lock lock(queue_mutex_); 94 | if (!push_cv_.wait_for(lock, wait_duration, [this] { return !this->q_.empty(); })) 95 | { 96 | return false; 97 | } 98 | q_.pop_front(popped_item); 99 | pop_cv_.notify_one(); 100 | return true; 101 | } 102 | 103 | #endif 104 | 105 | size_t overrun_counter() 106 | { 107 | std::unique_lock lock(queue_mutex_); 108 | return q_.overrun_counter(); 109 | } 110 | 111 | private: 112 | std::mutex queue_mutex_; 113 | std::condition_variable push_cv_; 114 | std::condition_variable pop_cv_; 115 | spdlog::details::circular_q q_; 116 | }; 117 | } // namespace details 118 | } // namespace spdlog 119 | -------------------------------------------------------------------------------- /includes/spdlog/details/null_mutex.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | // null, no cost dummy "mutex" and dummy "atomic" int 9 | 10 | namespace spdlog { 11 | namespace details { 12 | struct null_mutex 13 | { 14 | void lock() const {} 15 | void unlock() const {} 16 | bool try_lock() const 17 | { 18 | return true; 19 | } 20 | }; 21 | 22 | struct null_atomic_int 23 | { 24 | int value; 25 | null_atomic_int() = default; 26 | 27 | explicit null_atomic_int(int new_value) 28 | : value(new_value) 29 | {} 30 | 31 | int load(std::memory_order = std::memory_order_relaxed) const 32 | { 33 | return value; 34 | } 35 | 36 | void store(int new_value, std::memory_order = std::memory_order_relaxed) 37 | { 38 | value = new_value; 39 | } 40 | 41 | int exchange(int new_value, std::memory_order = std::memory_order_relaxed) 42 | { 43 | std::swap(new_value, value); 44 | return new_value; // return value before the call 45 | } 46 | }; 47 | 48 | } // namespace details 49 | } // namespace spdlog 50 | -------------------------------------------------------------------------------- /includes/spdlog/details/os.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/common.h" 7 | #include // std::time_t 8 | 9 | namespace spdlog { 10 | namespace details { 11 | namespace os { 12 | 13 | spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT; 14 | 15 | std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; 16 | 17 | std::tm localtime() SPDLOG_NOEXCEPT; 18 | 19 | std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; 20 | 21 | std::tm gmtime() SPDLOG_NOEXCEPT; 22 | 23 | // eol definition 24 | #if !defined(SPDLOG_EOL) 25 | #ifdef _WIN32 26 | #define SPDLOG_EOL "\r\n" 27 | #else 28 | #define SPDLOG_EOL "\n" 29 | #endif 30 | #endif 31 | 32 | SPDLOG_CONSTEXPR static const char *default_eol = SPDLOG_EOL; 33 | 34 | // folder separator 35 | #ifdef _WIN32 36 | const char folder_sep = '\\'; 37 | #else 38 | SPDLOG_CONSTEXPR static const char folder_sep = '/'; 39 | #endif 40 | 41 | void prevent_child_fd(FILE *f); 42 | 43 | // fopen_s on non windows for writing 44 | bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode); 45 | 46 | int remove(const filename_t &filename) SPDLOG_NOEXCEPT; 47 | 48 | int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT; 49 | 50 | // Return if file exists 51 | bool file_exists(const filename_t &filename) SPDLOG_NOEXCEPT; 52 | 53 | // Return file size according to open FILE* object 54 | size_t filesize(FILE *f); 55 | 56 | // Return utc offset in minutes or throw spdlog_ex on failure 57 | int utc_minutes_offset(const std::tm &tm = details::os::localtime()); 58 | 59 | // Return current thread id as size_t 60 | // It exists because the std::this_thread::get_id() is much slower(especially 61 | // under VS 2013) 62 | size_t _thread_id() SPDLOG_NOEXCEPT; 63 | 64 | // Return current thread id as size_t (from thread local storage) 65 | size_t thread_id() SPDLOG_NOEXCEPT; 66 | 67 | // This is avoid msvc issue in sleep_for that happens if the clock changes. 68 | // See https://github.com/gabime/spdlog/issues/609 69 | void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT; 70 | 71 | std::string filename_to_str(const filename_t &filename); 72 | 73 | int pid() SPDLOG_NOEXCEPT; 74 | 75 | // Determine if the terminal supports colors 76 | // Source: https://github.com/agauniyal/rang/ 77 | bool is_color_terminal() SPDLOG_NOEXCEPT; 78 | 79 | // Detrmine if the terminal attached 80 | // Source: https://github.com/agauniyal/rang/ 81 | bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; 82 | 83 | #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) 84 | void wstr_to_utf8buf(basic_string_view_t wstr, memory_buf_t &target); 85 | #endif 86 | 87 | } // namespace os 88 | } // namespace details 89 | } // namespace spdlog 90 | 91 | #ifdef SPDLOG_HEADER_ONLY 92 | #include "os-inl.h" 93 | #endif 94 | -------------------------------------------------------------------------------- /includes/spdlog/details/pattern_formatter.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/common.h" 7 | #include "spdlog/details/log_msg.h" 8 | #include "spdlog/details/os.h" 9 | #include "spdlog/formatter.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace spdlog { 19 | namespace details { 20 | 21 | // padding information. 22 | struct padding_info 23 | { 24 | enum pad_side 25 | { 26 | left, 27 | right, 28 | center 29 | }; 30 | 31 | padding_info() = default; 32 | padding_info(size_t width, padding_info::pad_side side) 33 | : width_(width) 34 | , side_(side) 35 | {} 36 | 37 | bool enabled() const 38 | { 39 | return width_ != 0; 40 | } 41 | const size_t width_ = 0; 42 | const pad_side side_ = left; 43 | }; 44 | 45 | class flag_formatter 46 | { 47 | public: 48 | explicit flag_formatter(padding_info padinfo) 49 | : padinfo_(padinfo) 50 | {} 51 | flag_formatter() = default; 52 | virtual ~flag_formatter() = default; 53 | virtual void format(const details::log_msg &msg, const std::tm &tm_time, memory_buf_t &dest) = 0; 54 | 55 | protected: 56 | padding_info padinfo_; 57 | }; 58 | 59 | } // namespace details 60 | 61 | class pattern_formatter final : public formatter 62 | { 63 | public: 64 | explicit pattern_formatter( 65 | std::string pattern, pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol); 66 | 67 | // use default pattern is not given 68 | explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol); 69 | 70 | pattern_formatter(const pattern_formatter &other) = delete; 71 | pattern_formatter &operator=(const pattern_formatter &other) = delete; 72 | 73 | std::unique_ptr clone() const override; 74 | void format(const details::log_msg &msg, memory_buf_t &dest) override; 75 | 76 | private: 77 | std::string pattern_; 78 | std::string eol_; 79 | pattern_time_type pattern_time_type_; 80 | std::tm cached_tm_; 81 | std::chrono::seconds last_log_secs_; 82 | std::vector> formatters_; 83 | 84 | std::tm get_time_(const details::log_msg &msg); 85 | template 86 | void handle_flag_(char flag, details::padding_info padding); 87 | 88 | // Extract given pad spec (e.g. %8X) 89 | // Advance the given it pass the end of the padding spec found (if any) 90 | // Return padding. 91 | details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end); 92 | 93 | void compile_pattern_(const std::string &pattern); 94 | }; 95 | } // namespace spdlog 96 | 97 | #ifdef SPDLOG_HEADER_ONLY 98 | #include "pattern_formatter-inl.h" 99 | #endif 100 | -------------------------------------------------------------------------------- /includes/spdlog/details/periodic_worker-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/details/periodic_worker.h" 8 | #endif 9 | 10 | namespace spdlog { 11 | namespace details { 12 | 13 | SPDLOG_INLINE periodic_worker::periodic_worker(const std::function &callback_fun, std::chrono::seconds interval) 14 | { 15 | active_ = (interval > std::chrono::seconds::zero()); 16 | if (!active_) 17 | { 18 | return; 19 | } 20 | 21 | worker_thread_ = std::thread([this, callback_fun, interval]() { 22 | for (;;) 23 | { 24 | std::unique_lock lock(this->mutex_); 25 | if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; })) 26 | { 27 | return; // active_ == false, so exit this thread 28 | } 29 | callback_fun(); 30 | } 31 | }); 32 | } 33 | 34 | // stop the worker thread and join it 35 | SPDLOG_INLINE periodic_worker::~periodic_worker() 36 | { 37 | if (worker_thread_.joinable()) 38 | { 39 | { 40 | std::lock_guard lock(mutex_); 41 | active_ = false; 42 | } 43 | cv_.notify_one(); 44 | worker_thread_.join(); 45 | } 46 | } 47 | 48 | } // namespace details 49 | } // namespace spdlog 50 | -------------------------------------------------------------------------------- /includes/spdlog/details/periodic_worker.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | // periodic worker thread - periodically executes the given callback function. 7 | // 8 | // RAII over the owned thread: 9 | // creates the thread on construction. 10 | // stops and joins the thread on destruction (if the thread is executing a callback, wait for it to finish first). 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | namespace spdlog { 18 | namespace details { 19 | 20 | class periodic_worker 21 | { 22 | public: 23 | periodic_worker(const std::function &callback_fun, std::chrono::seconds interval); 24 | periodic_worker(const periodic_worker &) = delete; 25 | periodic_worker &operator=(const periodic_worker &) = delete; 26 | // stop the worker thread and join it 27 | ~periodic_worker(); 28 | 29 | private: 30 | bool active_; 31 | std::thread worker_thread_; 32 | std::mutex mutex_; 33 | std::condition_variable cv_; 34 | }; 35 | } // namespace details 36 | } // namespace spdlog 37 | 38 | #ifdef SPDLOG_HEADER_ONLY 39 | #include "periodic_worker-inl.h" 40 | #endif 41 | -------------------------------------------------------------------------------- /includes/spdlog/details/registry-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/details/registry.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | #include "spdlog/details/periodic_worker.h" 12 | #include "spdlog/logger.h" 13 | #include "spdlog/details/pattern_formatter.h" 14 | 15 | #ifndef SPDLOG_DISABLE_DEFAULT_LOGGER 16 | // support for the default stdout color logger 17 | #ifdef _WIN32 18 | #include "spdlog/sinks/wincolor_sink.h" 19 | #else 20 | #include "spdlog/sinks/ansicolor_sink.h" 21 | #endif 22 | #endif // SPDLOG_DISABLE_DEFAULT_LOGGER 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | namespace spdlog { 31 | namespace details { 32 | 33 | SPDLOG_INLINE registry::registry() 34 | : formatter_(new pattern_formatter()) 35 | { 36 | 37 | #ifndef SPDLOG_DISABLE_DEFAULT_LOGGER 38 | // create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows). 39 | #ifdef _WIN32 40 | auto color_sink = std::make_shared(); 41 | #else 42 | auto color_sink = std::make_shared(); 43 | #endif 44 | 45 | const char *default_logger_name = ""; 46 | default_logger_ = std::make_shared(default_logger_name, std::move(color_sink)); 47 | loggers_[default_logger_name] = default_logger_; 48 | 49 | #endif // SPDLOG_DISABLE_DEFAULT_LOGGER 50 | } 51 | SPDLOG_INLINE void registry::register_logger(std::shared_ptr new_logger) 52 | { 53 | std::lock_guard lock(logger_map_mutex_); 54 | register_logger_(std::move(new_logger)); 55 | } 56 | 57 | SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr new_logger) 58 | { 59 | std::lock_guard lock(logger_map_mutex_); 60 | new_logger->set_formatter(formatter_->clone()); 61 | 62 | if (err_handler_) 63 | { 64 | new_logger->set_error_handler(err_handler_); 65 | } 66 | 67 | new_logger->set_level(level_); 68 | new_logger->flush_on(flush_level_); 69 | 70 | if (backtrace_n_messages_ > 0) 71 | { 72 | new_logger->enable_backtrace(backtrace_n_messages_); 73 | } 74 | 75 | if (automatic_registration_) 76 | { 77 | register_logger_(std::move(new_logger)); 78 | } 79 | } 80 | 81 | SPDLOG_INLINE std::shared_ptr registry::get(const std::string &logger_name) 82 | { 83 | std::lock_guard lock(logger_map_mutex_); 84 | auto found = loggers_.find(logger_name); 85 | return found == loggers_.end() ? nullptr : found->second; 86 | } 87 | 88 | SPDLOG_INLINE std::shared_ptr registry::default_logger() 89 | { 90 | std::lock_guard lock(logger_map_mutex_); 91 | return default_logger_; 92 | } 93 | 94 | // Return raw ptr to the default logger. 95 | // To be used directly by the spdlog default api (e.g. spdlog::info) 96 | // This make the default API faster, but cannot be used concurrently with set_default_logger(). 97 | // e.g do not call set_default_logger() from one thread while calling spdlog::info() from another. 98 | SPDLOG_INLINE logger *registry::get_default_raw() 99 | { 100 | return default_logger_.get(); 101 | } 102 | 103 | // set default logger. 104 | // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map. 105 | SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr new_default_logger) 106 | { 107 | std::lock_guard lock(logger_map_mutex_); 108 | // remove previous default logger from the map 109 | if (default_logger_ != nullptr) 110 | { 111 | loggers_.erase(default_logger_->name()); 112 | } 113 | if (new_default_logger != nullptr) 114 | { 115 | loggers_[new_default_logger->name()] = new_default_logger; 116 | } 117 | default_logger_ = std::move(new_default_logger); 118 | } 119 | 120 | SPDLOG_INLINE void registry::set_tp(std::shared_ptr tp) 121 | { 122 | std::lock_guard lock(tp_mutex_); 123 | tp_ = std::move(tp); 124 | } 125 | 126 | SPDLOG_INLINE std::shared_ptr registry::get_tp() 127 | { 128 | std::lock_guard lock(tp_mutex_); 129 | return tp_; 130 | } 131 | 132 | // Set global formatter. Each sink in each logger will get a clone of this object 133 | SPDLOG_INLINE void registry::set_formatter(std::unique_ptr formatter) 134 | { 135 | std::lock_guard lock(logger_map_mutex_); 136 | formatter_ = std::move(formatter); 137 | for (auto &l : loggers_) 138 | { 139 | l.second->set_formatter(formatter_->clone()); 140 | } 141 | } 142 | 143 | SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages) 144 | { 145 | std::lock_guard lock(logger_map_mutex_); 146 | backtrace_n_messages_ = n_messages; 147 | 148 | for (auto &l : loggers_) 149 | { 150 | l.second->enable_backtrace(n_messages); 151 | } 152 | } 153 | 154 | SPDLOG_INLINE void registry::disable_backtrace() 155 | { 156 | std::lock_guard lock(logger_map_mutex_); 157 | backtrace_n_messages_ = 0; 158 | for (auto &l : loggers_) 159 | { 160 | l.second->disable_backtrace(); 161 | } 162 | } 163 | 164 | SPDLOG_INLINE void registry::set_level(level::level_enum log_level) 165 | { 166 | std::lock_guard lock(logger_map_mutex_); 167 | for (auto &l : loggers_) 168 | { 169 | l.second->set_level(log_level); 170 | } 171 | level_ = log_level; 172 | } 173 | 174 | SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) 175 | { 176 | std::lock_guard lock(logger_map_mutex_); 177 | for (auto &l : loggers_) 178 | { 179 | l.second->flush_on(log_level); 180 | } 181 | flush_level_ = log_level; 182 | } 183 | 184 | SPDLOG_INLINE void registry::flush_every(std::chrono::seconds interval) 185 | { 186 | std::lock_guard lock(flusher_mutex_); 187 | std::function clbk = std::bind(®istry::flush_all, this); 188 | periodic_flusher_ = details::make_unique(clbk, interval); 189 | } 190 | 191 | SPDLOG_INLINE void registry::set_error_handler(void (*handler)(const std::string &msg)) 192 | { 193 | std::lock_guard lock(logger_map_mutex_); 194 | for (auto &l : loggers_) 195 | { 196 | l.second->set_error_handler(handler); 197 | } 198 | err_handler_ = handler; 199 | } 200 | 201 | SPDLOG_INLINE void registry::apply_all(const std::function)> &fun) 202 | { 203 | std::lock_guard lock(logger_map_mutex_); 204 | for (auto &l : loggers_) 205 | { 206 | fun(l.second); 207 | } 208 | } 209 | 210 | SPDLOG_INLINE void registry::flush_all() 211 | { 212 | std::lock_guard lock(logger_map_mutex_); 213 | for (auto &l : loggers_) 214 | { 215 | l.second->flush(); 216 | } 217 | } 218 | 219 | SPDLOG_INLINE void registry::drop(const std::string &logger_name) 220 | { 221 | std::lock_guard lock(logger_map_mutex_); 222 | loggers_.erase(logger_name); 223 | if (default_logger_ && default_logger_->name() == logger_name) 224 | { 225 | default_logger_.reset(); 226 | } 227 | } 228 | 229 | SPDLOG_INLINE void registry::drop_all() 230 | { 231 | std::lock_guard lock(logger_map_mutex_); 232 | loggers_.clear(); 233 | default_logger_.reset(); 234 | } 235 | 236 | // clean all resources and threads started by the registry 237 | SPDLOG_INLINE void registry::shutdown() 238 | { 239 | { 240 | std::lock_guard lock(flusher_mutex_); 241 | periodic_flusher_.reset(); 242 | } 243 | 244 | drop_all(); 245 | 246 | { 247 | std::lock_guard lock(tp_mutex_); 248 | tp_.reset(); 249 | } 250 | } 251 | 252 | SPDLOG_INLINE std::recursive_mutex ®istry::tp_mutex() 253 | { 254 | return tp_mutex_; 255 | } 256 | 257 | SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_regsistration) 258 | { 259 | std::lock_guard lock(logger_map_mutex_); 260 | automatic_registration_ = automatic_regsistration; 261 | } 262 | 263 | SPDLOG_INLINE registry ®istry::instance() 264 | { 265 | static registry s_instance; 266 | return s_instance; 267 | } 268 | 269 | SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name) 270 | { 271 | if (loggers_.find(logger_name) != loggers_.end()) 272 | { 273 | SPDLOG_THROW(spdlog_ex("logger with name '" + logger_name + "' already exists")); 274 | } 275 | } 276 | 277 | SPDLOG_INLINE void registry::register_logger_(std::shared_ptr new_logger) 278 | { 279 | auto logger_name = new_logger->name(); 280 | throw_if_exists_(logger_name); 281 | loggers_[logger_name] = std::move(new_logger); 282 | } 283 | } // namespace details 284 | } // namespace spdlog 285 | -------------------------------------------------------------------------------- /includes/spdlog/details/registry.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | // Loggers registry of unique name->logger pointer 7 | // An attempt to create a logger with an already existing name will result with spdlog_ex exception. 8 | // If user requests a non existing logger, nullptr will be returned 9 | // This class is thread safe 10 | 11 | #include "spdlog/common.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace spdlog { 21 | class logger; 22 | 23 | namespace details { 24 | class thread_pool; 25 | class periodic_worker; 26 | 27 | class registry 28 | { 29 | public: 30 | registry(const registry &) = delete; 31 | registry &operator=(const registry &) = delete; 32 | 33 | void register_logger(std::shared_ptr new_logger); 34 | void initialize_logger(std::shared_ptr new_logger); 35 | std::shared_ptr get(const std::string &logger_name); 36 | std::shared_ptr default_logger(); 37 | 38 | // Return raw ptr to the default logger. 39 | // To be used directly by the spdlog default api (e.g. spdlog::info) 40 | // This make the default API faster, but cannot be used concurrently with set_default_logger(). 41 | // e.g do not call set_default_logger() from one thread while calling spdlog::info() from another. 42 | logger *get_default_raw(); 43 | 44 | // set default logger. 45 | // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map. 46 | void set_default_logger(std::shared_ptr new_default_logger); 47 | 48 | void set_tp(std::shared_ptr tp); 49 | 50 | std::shared_ptr get_tp(); 51 | 52 | // Set global formatter. Each sink in each logger will get a clone of this object 53 | void set_formatter(std::unique_ptr formatter); 54 | 55 | void enable_backtrace(size_t n_messages); 56 | 57 | void disable_backtrace(); 58 | 59 | void set_level(level::level_enum log_level); 60 | 61 | void flush_on(level::level_enum log_level); 62 | 63 | void flush_every(std::chrono::seconds interval); 64 | 65 | void set_error_handler(void (*handler)(const std::string &msg)); 66 | 67 | void apply_all(const std::function)> &fun); 68 | 69 | void flush_all(); 70 | 71 | void drop(const std::string &logger_name); 72 | 73 | void drop_all(); 74 | 75 | // clean all resources and threads started by the registry 76 | void shutdown(); 77 | 78 | std::recursive_mutex &tp_mutex(); 79 | 80 | void set_automatic_registration(bool automatic_regsistration); 81 | 82 | static registry &instance(); 83 | 84 | private: 85 | registry(); 86 | ~registry() = default; 87 | 88 | void throw_if_exists_(const std::string &logger_name); 89 | void register_logger_(std::shared_ptr new_logger); 90 | std::mutex logger_map_mutex_, flusher_mutex_; 91 | std::recursive_mutex tp_mutex_; 92 | std::unordered_map> loggers_; 93 | std::unique_ptr formatter_; 94 | level::level_enum level_ = level::info; 95 | level::level_enum flush_level_ = level::off; 96 | void (*err_handler_)(const std::string &msg); 97 | std::shared_ptr tp_; 98 | std::unique_ptr periodic_flusher_; 99 | std::shared_ptr default_logger_; 100 | bool automatic_registration_ = true; 101 | size_t backtrace_n_messages_ = 0; 102 | }; 103 | 104 | } // namespace details 105 | } // namespace spdlog 106 | 107 | #ifdef SPDLOG_HEADER_ONLY 108 | #include "registry-inl.h" 109 | #endif 110 | -------------------------------------------------------------------------------- /includes/spdlog/details/synchronous_factory.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "registry.h" 7 | 8 | namespace spdlog { 9 | 10 | // Default logger factory- creates synchronous loggers 11 | class logger; 12 | 13 | struct synchronous_factory 14 | { 15 | template 16 | static std::shared_ptr create(std::string logger_name, SinkArgs &&... args) 17 | { 18 | auto sink = std::make_shared(std::forward(args)...); 19 | auto new_logger = std::make_shared(std::move(logger_name), std::move(sink)); 20 | details::registry::instance().initialize_logger(new_logger); 21 | return new_logger; 22 | } 23 | }; 24 | } // namespace spdlog -------------------------------------------------------------------------------- /includes/spdlog/details/thread_pool-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/details/thread_pool.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | 12 | namespace spdlog { 13 | namespace details { 14 | 15 | SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n, std::function on_thread_start) 16 | : q_(q_max_items) 17 | { 18 | if (threads_n == 0 || threads_n > 1000) 19 | { 20 | SPDLOG_THROW(spdlog_ex("spdlog::thread_pool(): invalid threads_n param (valid " 21 | "range is 1-1000)")); 22 | } 23 | for (size_t i = 0; i < threads_n; i++) 24 | { 25 | threads_.emplace_back([this, on_thread_start] { 26 | on_thread_start(); 27 | this->thread_pool::worker_loop_(); 28 | }); 29 | } 30 | } 31 | 32 | SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n) 33 | : thread_pool(q_max_items, threads_n, [] {}) 34 | {} 35 | 36 | // message all threads to terminate gracefully join them 37 | SPDLOG_INLINE thread_pool::~thread_pool() 38 | { 39 | SPDLOG_TRY 40 | { 41 | for (size_t i = 0; i < threads_.size(); i++) 42 | { 43 | post_async_msg_(async_msg(async_msg_type::terminate), async_overflow_policy::block); 44 | } 45 | 46 | for (auto &t : threads_) 47 | { 48 | t.join(); 49 | } 50 | } 51 | SPDLOG_CATCH_ALL() {} 52 | } 53 | 54 | void SPDLOG_INLINE thread_pool::post_log(async_logger_ptr &&worker_ptr, const details::log_msg &msg, async_overflow_policy overflow_policy) 55 | { 56 | async_msg async_m(std::move(worker_ptr), async_msg_type::log, msg); 57 | post_async_msg_(std::move(async_m), overflow_policy); 58 | } 59 | 60 | void SPDLOG_INLINE thread_pool::post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy) 61 | { 62 | post_async_msg_(async_msg(std::move(worker_ptr), async_msg_type::flush), overflow_policy); 63 | } 64 | 65 | size_t SPDLOG_INLINE thread_pool::overrun_counter() 66 | { 67 | return q_.overrun_counter(); 68 | } 69 | 70 | void SPDLOG_INLINE thread_pool::post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy) 71 | { 72 | if (overflow_policy == async_overflow_policy::block) 73 | { 74 | q_.enqueue(std::move(new_msg)); 75 | } 76 | else 77 | { 78 | q_.enqueue_nowait(std::move(new_msg)); 79 | } 80 | } 81 | 82 | void SPDLOG_INLINE thread_pool::worker_loop_() 83 | { 84 | while (process_next_msg_()) {}; 85 | } 86 | 87 | // process next message in the queue 88 | // return true if this thread should still be active (while no terminate msg 89 | // was received) 90 | bool SPDLOG_INLINE thread_pool::process_next_msg_() 91 | { 92 | async_msg incoming_async_msg; 93 | bool dequeued = q_.dequeue_for(incoming_async_msg, std::chrono::seconds(10)); 94 | if (!dequeued) 95 | { 96 | return true; 97 | } 98 | 99 | switch (incoming_async_msg.msg_type) 100 | { 101 | case async_msg_type::log: 102 | { 103 | incoming_async_msg.worker_ptr->backend_sink_it_(incoming_async_msg); 104 | return true; 105 | } 106 | case async_msg_type::flush: 107 | { 108 | incoming_async_msg.worker_ptr->backend_flush_(); 109 | return true; 110 | } 111 | 112 | case async_msg_type::terminate: 113 | { 114 | return false; 115 | } 116 | 117 | default: 118 | { 119 | assert(false && "Unexpected async_msg_type"); 120 | } 121 | } 122 | 123 | return true; 124 | } 125 | 126 | } // namespace details 127 | } // namespace spdlog 128 | -------------------------------------------------------------------------------- /includes/spdlog/details/thread_pool.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/log_msg_buffer.h" 7 | #include "spdlog/details/mpmc_blocking_q.h" 8 | #include "spdlog/details/os.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace spdlog { 17 | class async_logger; 18 | 19 | namespace details { 20 | 21 | using async_logger_ptr = std::shared_ptr; 22 | 23 | enum class async_msg_type 24 | { 25 | log, 26 | flush, 27 | terminate 28 | }; 29 | 30 | #include "spdlog/details/log_msg_buffer.h" 31 | // Async msg to move to/from the queue 32 | // Movable only. should never be copied 33 | struct async_msg : log_msg_buffer 34 | { 35 | async_msg_type msg_type{async_msg_type::log}; 36 | async_logger_ptr worker_ptr; 37 | 38 | async_msg() = default; 39 | ~async_msg() = default; 40 | 41 | // should only be moved in or out of the queue.. 42 | async_msg(const async_msg &) = delete; 43 | 44 | // support for vs2013 move 45 | #if defined(_MSC_VER) && _MSC_VER <= 1800 46 | async_msg(async_msg &&other) 47 | : log_msg_buffer(std::move(other)) 48 | , msg_type(other.msg_type) 49 | , worker_ptr(std::move(other.worker_ptr)) 50 | {} 51 | 52 | async_msg &operator=(async_msg &&other) 53 | { 54 | *static_cast(this) = std::move(other); 55 | msg_type = other.msg_type; 56 | worker_ptr = std::move(other.worker_ptr); 57 | return *this; 58 | } 59 | #else // (_MSC_VER) && _MSC_VER <= 1800 60 | async_msg(async_msg &&) = default; 61 | async_msg &operator=(async_msg &&) = default; 62 | #endif 63 | 64 | // construct from log_msg with given type 65 | async_msg(async_logger_ptr &&worker, async_msg_type the_type, const details::log_msg &m) 66 | : log_msg_buffer{m} 67 | , msg_type{the_type} 68 | , worker_ptr{std::move(worker)} 69 | {} 70 | 71 | async_msg(async_logger_ptr &&worker, async_msg_type the_type) 72 | : log_msg_buffer{} 73 | , msg_type{the_type} 74 | , worker_ptr{std::move(worker)} 75 | {} 76 | 77 | explicit async_msg(async_msg_type the_type) 78 | : async_msg{nullptr, the_type} 79 | {} 80 | }; 81 | 82 | class thread_pool 83 | { 84 | public: 85 | using item_type = async_msg; 86 | using q_type = details::mpmc_blocking_queue; 87 | 88 | thread_pool(size_t q_max_items, size_t threads_n, std::function on_thread_start); 89 | thread_pool(size_t q_max_items, size_t threads_n); 90 | 91 | // message all threads to terminate gracefully join them 92 | ~thread_pool(); 93 | 94 | thread_pool(const thread_pool &) = delete; 95 | thread_pool &operator=(thread_pool &&) = delete; 96 | 97 | void post_log(async_logger_ptr &&worker_ptr, const details::log_msg &msg, async_overflow_policy overflow_policy); 98 | void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy); 99 | size_t overrun_counter(); 100 | 101 | private: 102 | q_type q_; 103 | 104 | std::vector threads_; 105 | 106 | void post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy); 107 | void worker_loop_(); 108 | 109 | // process next message in the queue 110 | // return true if this thread should still be active (while no terminate msg 111 | // was received) 112 | bool process_next_msg_(); 113 | }; 114 | 115 | } // namespace details 116 | } // namespace spdlog 117 | 118 | #ifdef SPDLOG_HEADER_ONLY 119 | #include "thread_pool-inl.h" 120 | #endif 121 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/bin_to_hex.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2015 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Support for logging binary data as hex 10 | // format flags: 11 | // {:X} - print in uppercase. 12 | // {:s} - don't separate each byte with space. 13 | // {:p} - don't print the position on each line start. 14 | // {:n} - don't split the output to lines. 15 | 16 | // 17 | // Examples: 18 | // 19 | // std::vector v(200, 0x0b); 20 | // logger->info("Some buffer {}", spdlog::to_hex(v)); 21 | // char buf[128]; 22 | // logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf))); 23 | 24 | namespace spdlog { 25 | namespace details { 26 | 27 | template 28 | class bytes_range 29 | { 30 | public: 31 | bytes_range(It range_begin, It range_end) 32 | : begin_(range_begin) 33 | , end_(range_end) 34 | {} 35 | 36 | It begin() const 37 | { 38 | return begin_; 39 | } 40 | It end() const 41 | { 42 | return end_; 43 | } 44 | 45 | private: 46 | It begin_, end_; 47 | }; 48 | } // namespace details 49 | 50 | // create a bytes_range that wraps the given container 51 | template 52 | inline details::bytes_range to_hex(const Container &container) 53 | { 54 | static_assert(sizeof(typename Container::value_type) == 1, "sizeof(Container::value_type) != 1"); 55 | using Iter = typename Container::const_iterator; 56 | return details::bytes_range(std::begin(container), std::end(container)); 57 | } 58 | 59 | // create bytes_range from ranges 60 | template 61 | inline details::bytes_range to_hex(const It range_begin, const It range_end) 62 | { 63 | return details::bytes_range(range_begin, range_end); 64 | } 65 | 66 | } // namespace spdlog 67 | 68 | namespace fmt { 69 | 70 | template 71 | struct formatter> 72 | { 73 | const std::size_t line_size = 100; 74 | const char delimiter = ' '; 75 | 76 | bool put_newlines = true; 77 | bool put_delimiters = true; 78 | bool use_uppercase = false; 79 | bool put_positions = true; // position on start of each line 80 | 81 | // parse the format string flags 82 | template 83 | auto parse(ParseContext &ctx) -> decltype(ctx.begin()) 84 | { 85 | auto it = ctx.begin(); 86 | while (*it && *it != '}') 87 | { 88 | switch (*it) 89 | { 90 | case 'X': 91 | use_uppercase = true; 92 | break; 93 | case 's': 94 | put_delimiters = false; 95 | break; 96 | case 'p': 97 | put_positions = false; 98 | break; 99 | case 'n': 100 | put_newlines = false; 101 | break; 102 | } 103 | 104 | ++it; 105 | } 106 | return it; 107 | } 108 | 109 | // format the given bytes range as hex 110 | template 111 | auto format(const spdlog::details::bytes_range &the_range, FormatContext &ctx) -> decltype(ctx.out()) 112 | { 113 | SPDLOG_CONSTEXPR const char *hex_upper = "0123456789ABCDEF"; 114 | SPDLOG_CONSTEXPR const char *hex_lower = "0123456789abcdef"; 115 | const char *hex_chars = use_uppercase ? hex_upper : hex_lower; 116 | 117 | std::size_t pos = 0; 118 | std::size_t column = line_size; 119 | #if FMT_VERSION < 60000 120 | auto inserter = ctx.begin(); 121 | #else 122 | auto inserter = ctx.out(); 123 | #endif 124 | 125 | for (auto &item : the_range) 126 | { 127 | auto ch = static_cast(item); 128 | pos++; 129 | 130 | if (put_newlines && column >= line_size) 131 | { 132 | column = put_newline(inserter, pos); 133 | 134 | // put first byte without delimiter in front of it 135 | *inserter++ = hex_chars[(ch >> 4) & 0x0f]; 136 | *inserter++ = hex_chars[ch & 0x0f]; 137 | column += 2; 138 | continue; 139 | } 140 | 141 | if (put_delimiters) 142 | { 143 | *inserter++ = delimiter; 144 | ++column; 145 | } 146 | 147 | *inserter++ = hex_chars[(ch >> 4) & 0x0f]; 148 | *inserter++ = hex_chars[ch & 0x0f]; 149 | column += 2; 150 | } 151 | return inserter; 152 | } 153 | 154 | // put newline(and position header) 155 | // return the next column 156 | template 157 | std::size_t put_newline(It inserter, std::size_t pos) 158 | { 159 | #ifdef _WIN32 160 | *inserter++ = '\r'; 161 | #endif 162 | *inserter++ = '\n'; 163 | 164 | if (put_positions) 165 | { 166 | fmt::format_to(inserter, "{:<04X}: ", pos - 1); 167 | return 7; 168 | } 169 | else 170 | { 171 | return 1; 172 | } 173 | } 174 | }; 175 | } // namespace fmt 176 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/bundled/LICENSE.rst: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - present, Victor Zverovich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | --- Optional exception to the license --- 23 | 24 | As an exception, if, as a result of your compiling your source code, portions 25 | of this Software are embedded into a machine-executable object form of such 26 | source code, you may redistribute such embedded portions in such object form 27 | without including the above copyright and permission notices. 28 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/bundled/locale.h: -------------------------------------------------------------------------------- 1 | // Formatting library for C++ - std::locale support 2 | // 3 | // Copyright (c) 2012 - present, Victor Zverovich 4 | // All rights reserved. 5 | // 6 | // For the license information refer to format.h. 7 | 8 | #ifndef FMT_LOCALE_H_ 9 | #define FMT_LOCALE_H_ 10 | 11 | #include 12 | #include "format.h" 13 | 14 | FMT_BEGIN_NAMESPACE 15 | 16 | namespace internal { 17 | template 18 | typename buffer_context::iterator vformat_to( 19 | const std::locale& loc, buffer& buf, 20 | basic_string_view format_str, 21 | basic_format_args> args) { 22 | using range = buffer_range; 23 | return vformat_to>(buf, to_string_view(format_str), args, 24 | internal::locale_ref(loc)); 25 | } 26 | 27 | template 28 | std::basic_string vformat(const std::locale& loc, 29 | basic_string_view format_str, 30 | basic_format_args> args) { 31 | basic_memory_buffer buffer; 32 | internal::vformat_to(loc, buffer, format_str, args); 33 | return fmt::to_string(buffer); 34 | } 35 | } // namespace internal 36 | 37 | template > 38 | inline std::basic_string vformat( 39 | const std::locale& loc, const S& format_str, 40 | basic_format_args> args) { 41 | return internal::vformat(loc, to_string_view(format_str), args); 42 | } 43 | 44 | template > 45 | inline std::basic_string format(const std::locale& loc, 46 | const S& format_str, Args&&... args) { 47 | return internal::vformat( 48 | loc, to_string_view(format_str), 49 | {internal::make_args_checked(format_str, args...)}); 50 | } 51 | 52 | template ::value, char_t>> 55 | inline OutputIt vformat_to(OutputIt out, const std::locale& loc, 56 | const S& format_str, 57 | format_args_t args) { 58 | using range = internal::output_range; 59 | return vformat_to>( 60 | range(out), to_string_view(format_str), args, internal::locale_ref(loc)); 61 | } 62 | 63 | template ::value&& 65 | internal::is_string::value)> 66 | inline OutputIt format_to(OutputIt out, const std::locale& loc, 67 | const S& format_str, Args&&... args) { 68 | internal::check_format_string(format_str); 69 | using context = format_context_t>; 70 | format_arg_store as{args...}; 71 | return vformat_to(out, loc, to_string_view(format_str), 72 | basic_format_args(as)); 73 | } 74 | 75 | FMT_END_NAMESPACE 76 | 77 | #endif // FMT_LOCALE_H_ 78 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/bundled/ostream.h: -------------------------------------------------------------------------------- 1 | // Formatting library for C++ - std::ostream support 2 | // 3 | // Copyright (c) 2012 - present, Victor Zverovich 4 | // All rights reserved. 5 | // 6 | // For the license information refer to format.h. 7 | 8 | #ifndef FMT_OSTREAM_H_ 9 | #define FMT_OSTREAM_H_ 10 | 11 | #include 12 | #include "format.h" 13 | 14 | FMT_BEGIN_NAMESPACE 15 | namespace internal { 16 | 17 | template class formatbuf : public std::basic_streambuf { 18 | private: 19 | using int_type = typename std::basic_streambuf::int_type; 20 | using traits_type = typename std::basic_streambuf::traits_type; 21 | 22 | buffer& buffer_; 23 | 24 | public: 25 | formatbuf(buffer& buf) : buffer_(buf) {} 26 | 27 | protected: 28 | // The put-area is actually always empty. This makes the implementation 29 | // simpler and has the advantage that the streambuf and the buffer are always 30 | // in sync and sputc never writes into uninitialized memory. The obvious 31 | // disadvantage is that each call to sputc always results in a (virtual) call 32 | // to overflow. There is no disadvantage here for sputn since this always 33 | // results in a call to xsputn. 34 | 35 | int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE { 36 | if (!traits_type::eq_int_type(ch, traits_type::eof())) 37 | buffer_.push_back(static_cast(ch)); 38 | return ch; 39 | } 40 | 41 | std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE { 42 | buffer_.append(s, s + count); 43 | return count; 44 | } 45 | }; 46 | 47 | template struct test_stream : std::basic_ostream { 48 | private: 49 | struct null; 50 | // Hide all operator<< from std::basic_ostream. 51 | void operator<<(null); 52 | }; 53 | 54 | // Checks if T has a user-defined operator<< (e.g. not a member of 55 | // std::ostream). 56 | template class is_streamable { 57 | private: 58 | template 59 | static decltype((void)(std::declval&>() 60 | << std::declval()), 61 | std::true_type()) 62 | test(int); 63 | 64 | template static std::false_type test(...); 65 | 66 | using result = decltype(test(0)); 67 | 68 | public: 69 | static const bool value = result::value; 70 | }; 71 | 72 | // Write the content of buf to os. 73 | template 74 | void write(std::basic_ostream& os, buffer& buf) { 75 | const Char* buf_data = buf.data(); 76 | using unsigned_streamsize = std::make_unsigned::type; 77 | unsigned_streamsize size = buf.size(); 78 | unsigned_streamsize max_size = 79 | to_unsigned((std::numeric_limits::max)()); 80 | do { 81 | unsigned_streamsize n = size <= max_size ? size : max_size; 82 | os.write(buf_data, static_cast(n)); 83 | buf_data += n; 84 | size -= n; 85 | } while (size != 0); 86 | } 87 | 88 | template 89 | void format_value(buffer& buf, const T& value) { 90 | formatbuf format_buf(buf); 91 | std::basic_ostream output(&format_buf); 92 | output.exceptions(std::ios_base::failbit | std::ios_base::badbit); 93 | output << value; 94 | buf.resize(buf.size()); 95 | } 96 | 97 | // Formats an object of type T that has an overloaded ostream operator<<. 98 | template 99 | struct fallback_formatter::value>> 100 | : formatter, Char> { 101 | template 102 | auto format(const T& value, Context& ctx) -> decltype(ctx.out()) { 103 | basic_memory_buffer buffer; 104 | format_value(buffer, value); 105 | basic_string_view str(buffer.data(), buffer.size()); 106 | return formatter, Char>::format(str, ctx); 107 | } 108 | }; 109 | } // namespace internal 110 | 111 | template 112 | void vprint(std::basic_ostream& os, basic_string_view format_str, 113 | basic_format_args> args) { 114 | basic_memory_buffer buffer; 115 | internal::vformat_to(buffer, format_str, args); 116 | internal::write(os, buffer); 117 | } 118 | 119 | /** 120 | \rst 121 | Prints formatted data to the stream *os*. 122 | 123 | **Example**:: 124 | 125 | fmt::print(cerr, "Don't {}!", "panic"); 126 | \endrst 127 | */ 128 | template ::value, char_t>> 130 | void print(std::basic_ostream& os, const S& format_str, Args&&... args) { 131 | vprint(os, to_string_view(format_str), 132 | {internal::make_args_checked(format_str, args...)}); 133 | } 134 | FMT_END_NAMESPACE 135 | 136 | #endif // FMT_OSTREAM_H_ 137 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/bundled/posix.h: -------------------------------------------------------------------------------- 1 | // A C++ interface to POSIX functions. 2 | // 3 | // Copyright (c) 2012 - 2016, Victor Zverovich 4 | // All rights reserved. 5 | // 6 | // For the license information refer to format.h. 7 | 8 | #ifndef FMT_POSIX_H_ 9 | #define FMT_POSIX_H_ 10 | 11 | #if defined(__MINGW32__) || defined(__CYGWIN__) 12 | // Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/. 13 | # undef __STRICT_ANSI__ 14 | #endif 15 | 16 | #include 17 | #include // for O_RDONLY 18 | #include // for locale_t 19 | #include 20 | #include // for strtod_l 21 | 22 | #include 23 | 24 | #if defined __APPLE__ || defined(__FreeBSD__) 25 | # include // for LC_NUMERIC_MASK on OS X 26 | #endif 27 | 28 | #include "format.h" 29 | 30 | #ifndef FMT_POSIX 31 | # if defined(_WIN32) && !defined(__MINGW32__) 32 | // Fix warnings about deprecated symbols. 33 | # define FMT_POSIX(call) _##call 34 | # else 35 | # define FMT_POSIX(call) call 36 | # endif 37 | #endif 38 | 39 | // Calls to system functions are wrapped in FMT_SYSTEM for testability. 40 | #ifdef FMT_SYSTEM 41 | # define FMT_POSIX_CALL(call) FMT_SYSTEM(call) 42 | #else 43 | # define FMT_SYSTEM(call) call 44 | # ifdef _WIN32 45 | // Fix warnings about deprecated symbols. 46 | # define FMT_POSIX_CALL(call) ::_##call 47 | # else 48 | # define FMT_POSIX_CALL(call) ::call 49 | # endif 50 | #endif 51 | 52 | // Retries the expression while it evaluates to error_result and errno 53 | // equals to EINTR. 54 | #ifndef _WIN32 55 | # define FMT_RETRY_VAL(result, expression, error_result) \ 56 | do { \ 57 | result = (expression); \ 58 | } while (result == error_result && errno == EINTR) 59 | #else 60 | # define FMT_RETRY_VAL(result, expression, error_result) result = (expression) 61 | #endif 62 | 63 | #define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1) 64 | 65 | FMT_BEGIN_NAMESPACE 66 | 67 | /** 68 | \rst 69 | A reference to a null-terminated string. It can be constructed from a C 70 | string or ``std::string``. 71 | 72 | You can use one of the following type aliases for common character types: 73 | 74 | +---------------+-----------------------------+ 75 | | Type | Definition | 76 | +===============+=============================+ 77 | | cstring_view | basic_cstring_view | 78 | +---------------+-----------------------------+ 79 | | wcstring_view | basic_cstring_view | 80 | +---------------+-----------------------------+ 81 | 82 | This class is most useful as a parameter type to allow passing 83 | different types of strings to a function, for example:: 84 | 85 | template 86 | std::string format(cstring_view format_str, const Args & ... args); 87 | 88 | format("{}", 42); 89 | format(std::string("{}"), 42); 90 | \endrst 91 | */ 92 | template class basic_cstring_view { 93 | private: 94 | const Char* data_; 95 | 96 | public: 97 | /** Constructs a string reference object from a C string. */ 98 | basic_cstring_view(const Char* s) : data_(s) {} 99 | 100 | /** 101 | \rst 102 | Constructs a string reference from an ``std::string`` object. 103 | \endrst 104 | */ 105 | basic_cstring_view(const std::basic_string& s) : data_(s.c_str()) {} 106 | 107 | /** Returns the pointer to a C string. */ 108 | const Char* c_str() const { return data_; } 109 | }; 110 | 111 | using cstring_view = basic_cstring_view; 112 | using wcstring_view = basic_cstring_view; 113 | 114 | // An error code. 115 | class error_code { 116 | private: 117 | int value_; 118 | 119 | public: 120 | explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {} 121 | 122 | int get() const FMT_NOEXCEPT { return value_; } 123 | }; 124 | 125 | // A buffered file. 126 | class buffered_file { 127 | private: 128 | FILE* file_; 129 | 130 | friend class file; 131 | 132 | explicit buffered_file(FILE* f) : file_(f) {} 133 | 134 | public: 135 | // Constructs a buffered_file object which doesn't represent any file. 136 | buffered_file() FMT_NOEXCEPT : file_(nullptr) {} 137 | 138 | // Destroys the object closing the file it represents if any. 139 | FMT_API ~buffered_file() FMT_NOEXCEPT; 140 | 141 | private: 142 | buffered_file(const buffered_file&) = delete; 143 | void operator=(const buffered_file&) = delete; 144 | 145 | public: 146 | buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) { 147 | other.file_ = nullptr; 148 | } 149 | 150 | buffered_file& operator=(buffered_file&& other) { 151 | close(); 152 | file_ = other.file_; 153 | other.file_ = nullptr; 154 | return *this; 155 | } 156 | 157 | // Opens a file. 158 | FMT_API buffered_file(cstring_view filename, cstring_view mode); 159 | 160 | // Closes the file. 161 | FMT_API void close(); 162 | 163 | // Returns the pointer to a FILE object representing this file. 164 | FILE* get() const FMT_NOEXCEPT { return file_; } 165 | 166 | // We place parentheses around fileno to workaround a bug in some versions 167 | // of MinGW that define fileno as a macro. 168 | FMT_API int(fileno)() const; 169 | 170 | void vprint(string_view format_str, format_args args) { 171 | fmt::vprint(file_, format_str, args); 172 | } 173 | 174 | template 175 | inline void print(string_view format_str, const Args&... args) { 176 | vprint(format_str, make_format_args(args...)); 177 | } 178 | }; 179 | 180 | // A file. Closed file is represented by a file object with descriptor -1. 181 | // Methods that are not declared with FMT_NOEXCEPT may throw 182 | // fmt::system_error in case of failure. Note that some errors such as 183 | // closing the file multiple times will cause a crash on Windows rather 184 | // than an exception. You can get standard behavior by overriding the 185 | // invalid parameter handler with _set_invalid_parameter_handler. 186 | class file { 187 | private: 188 | int fd_; // File descriptor. 189 | 190 | // Constructs a file object with a given descriptor. 191 | explicit file(int fd) : fd_(fd) {} 192 | 193 | public: 194 | // Possible values for the oflag argument to the constructor. 195 | enum { 196 | RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only. 197 | WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only. 198 | RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing. 199 | }; 200 | 201 | // Constructs a file object which doesn't represent any file. 202 | file() FMT_NOEXCEPT : fd_(-1) {} 203 | 204 | // Opens a file and constructs a file object representing this file. 205 | FMT_API file(cstring_view path, int oflag); 206 | 207 | private: 208 | file(const file&) = delete; 209 | void operator=(const file&) = delete; 210 | 211 | public: 212 | file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; } 213 | 214 | file& operator=(file&& other) { 215 | close(); 216 | fd_ = other.fd_; 217 | other.fd_ = -1; 218 | return *this; 219 | } 220 | 221 | // Destroys the object closing the file it represents if any. 222 | FMT_API ~file() FMT_NOEXCEPT; 223 | 224 | // Returns the file descriptor. 225 | int descriptor() const FMT_NOEXCEPT { return fd_; } 226 | 227 | // Closes the file. 228 | FMT_API void close(); 229 | 230 | // Returns the file size. The size has signed type for consistency with 231 | // stat::st_size. 232 | FMT_API long long size() const; 233 | 234 | // Attempts to read count bytes from the file into the specified buffer. 235 | FMT_API std::size_t read(void* buffer, std::size_t count); 236 | 237 | // Attempts to write count bytes from the specified buffer to the file. 238 | FMT_API std::size_t write(const void* buffer, std::size_t count); 239 | 240 | // Duplicates a file descriptor with the dup function and returns 241 | // the duplicate as a file object. 242 | FMT_API static file dup(int fd); 243 | 244 | // Makes fd be the copy of this file descriptor, closing fd first if 245 | // necessary. 246 | FMT_API void dup2(int fd); 247 | 248 | // Makes fd be the copy of this file descriptor, closing fd first if 249 | // necessary. 250 | FMT_API void dup2(int fd, error_code& ec) FMT_NOEXCEPT; 251 | 252 | // Creates a pipe setting up read_end and write_end file objects for reading 253 | // and writing respectively. 254 | FMT_API static void pipe(file& read_end, file& write_end); 255 | 256 | // Creates a buffered_file object associated with this file and detaches 257 | // this file object from the file. 258 | FMT_API buffered_file fdopen(const char* mode); 259 | }; 260 | 261 | // Returns the memory page size. 262 | long getpagesize(); 263 | 264 | #ifdef FMT_LOCALE 265 | // A "C" numeric locale. 266 | class Locale { 267 | private: 268 | # ifdef _WIN32 269 | using locale_t = _locale_t; 270 | 271 | enum { LC_NUMERIC_MASK = LC_NUMERIC }; 272 | 273 | static locale_t newlocale(int category_mask, const char* locale, locale_t) { 274 | return _create_locale(category_mask, locale); 275 | } 276 | 277 | static void freelocale(locale_t locale) { _free_locale(locale); } 278 | 279 | static double strtod_l(const char* nptr, char** endptr, _locale_t locale) { 280 | return _strtod_l(nptr, endptr, locale); 281 | } 282 | # endif 283 | 284 | locale_t locale_; 285 | 286 | Locale(const Locale&) = delete; 287 | void operator=(const Locale&) = delete; 288 | 289 | public: 290 | using type = locale_t; 291 | 292 | Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", nullptr)) { 293 | if (!locale_) FMT_THROW(system_error(errno, "cannot create locale")); 294 | } 295 | ~Locale() { freelocale(locale_); } 296 | 297 | type get() const { return locale_; } 298 | 299 | // Converts string to floating-point number and advances str past the end 300 | // of the parsed input. 301 | double strtod(const char*& str) const { 302 | char* end = nullptr; 303 | double result = strtod_l(str, &end, locale_); 304 | str = end; 305 | return result; 306 | } 307 | }; 308 | #endif // FMT_LOCALE 309 | FMT_END_NAMESPACE 310 | 311 | #endif // FMT_POSIX_H_ 312 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/bundled/ranges.h: -------------------------------------------------------------------------------- 1 | // Formatting library for C++ - experimental range support 2 | // 3 | // Copyright (c) 2012 - present, Victor Zverovich 4 | // All rights reserved. 5 | // 6 | // For the license information refer to format.h. 7 | // 8 | // Copyright (c) 2018 - present, Remotion (Igor Schulz) 9 | // All Rights Reserved 10 | // {fmt} support for ranges, containers and types tuple interface. 11 | 12 | #ifndef FMT_RANGES_H_ 13 | #define FMT_RANGES_H_ 14 | 15 | #include 16 | #include "format.h" 17 | 18 | // output only up to N items from the range. 19 | #ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT 20 | # define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256 21 | #endif 22 | 23 | FMT_BEGIN_NAMESPACE 24 | 25 | template struct formatting_base { 26 | template 27 | FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { 28 | return ctx.begin(); 29 | } 30 | }; 31 | 32 | template 33 | struct formatting_range : formatting_base { 34 | static FMT_CONSTEXPR_DECL const std::size_t range_length_limit = 35 | FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the 36 | // range. 37 | Char prefix; 38 | Char delimiter; 39 | Char postfix; 40 | formatting_range() : prefix('{'), delimiter(','), postfix('}') {} 41 | static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true; 42 | static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false; 43 | }; 44 | 45 | template 46 | struct formatting_tuple : formatting_base { 47 | Char prefix; 48 | Char delimiter; 49 | Char postfix; 50 | formatting_tuple() : prefix('('), delimiter(','), postfix(')') {} 51 | static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true; 52 | static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false; 53 | }; 54 | 55 | namespace internal { 56 | 57 | template 58 | OutputIterator copy(const RangeT& range, OutputIterator out) { 59 | for (auto it = range.begin(), end = range.end(); it != end; ++it) 60 | *out++ = *it; 61 | return out; 62 | } 63 | 64 | template 65 | OutputIterator copy(const char* str, OutputIterator out) { 66 | while (*str) *out++ = *str++; 67 | return out; 68 | } 69 | 70 | template 71 | OutputIterator copy(char ch, OutputIterator out) { 72 | *out++ = ch; 73 | return out; 74 | } 75 | 76 | /// Return true value if T has std::string interface, like std::string_view. 77 | template class is_like_std_string { 78 | template 79 | static auto check(U* p) 80 | -> decltype((void)p->find('a'), p->length(), (void)p->data(), int()); 81 | template static void check(...); 82 | 83 | public: 84 | static FMT_CONSTEXPR_DECL const bool value = 85 | is_string::value || !std::is_void(nullptr))>::value; 86 | }; 87 | 88 | template 89 | struct is_like_std_string> : std::true_type {}; 90 | 91 | template struct conditional_helper {}; 92 | 93 | template struct is_range_ : std::false_type {}; 94 | 95 | #if !FMT_MSC_VER || FMT_MSC_VER > 1800 96 | template 97 | struct is_range_< 98 | T, conditional_t().begin()), 100 | decltype(std::declval().end())>, 101 | void>> : std::true_type {}; 102 | #endif 103 | 104 | /// tuple_size and tuple_element check. 105 | template class is_tuple_like_ { 106 | template 107 | static auto check(U* p) 108 | -> decltype(std::tuple_size::value, 109 | (void)std::declval::type>(), 110 | int()); 111 | template static void check(...); 112 | 113 | public: 114 | static FMT_CONSTEXPR_DECL const bool value = 115 | !std::is_void(nullptr))>::value; 116 | }; 117 | 118 | // Check for integer_sequence 119 | #if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900 120 | template 121 | using integer_sequence = std::integer_sequence; 122 | template using index_sequence = std::index_sequence; 123 | template 124 | using make_index_sequence = std::make_index_sequence; 125 | #else 126 | template struct integer_sequence { 127 | using value_type = T; 128 | 129 | static FMT_CONSTEXPR std::size_t size() { return sizeof...(N); } 130 | }; 131 | 132 | template 133 | using index_sequence = integer_sequence; 134 | 135 | template 136 | struct make_integer_sequence : make_integer_sequence {}; 137 | template 138 | struct make_integer_sequence : integer_sequence {}; 139 | 140 | template 141 | using make_index_sequence = make_integer_sequence; 142 | #endif 143 | 144 | template 145 | void for_each(index_sequence, Tuple&& tup, F&& f) FMT_NOEXCEPT { 146 | using std::get; 147 | // using free function get(T) now. 148 | const int _[] = {0, ((void)f(get(tup)), 0)...}; 149 | (void)_; // blocks warnings 150 | } 151 | 152 | template 153 | FMT_CONSTEXPR make_index_sequence::value> get_indexes( 154 | T const&) { 155 | return {}; 156 | } 157 | 158 | template void for_each(Tuple&& tup, F&& f) { 159 | const auto indexes = get_indexes(tup); 160 | for_each(indexes, std::forward(tup), std::forward(f)); 161 | } 162 | 163 | template ::type>::value)> 165 | FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) { 166 | return add_space ? " {}" : "{}"; 167 | } 168 | 169 | template ::type>::value)> 171 | FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) { 172 | return add_space ? " \"{}\"" : "\"{}\""; 173 | } 174 | 175 | FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char*) { 176 | return add_space ? " \"{}\"" : "\"{}\""; 177 | } 178 | FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) { 179 | return add_space ? L" \"{}\"" : L"\"{}\""; 180 | } 181 | 182 | FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char) { 183 | return add_space ? " '{}'" : "'{}'"; 184 | } 185 | FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) { 186 | return add_space ? L" '{}'" : L"'{}'"; 187 | } 188 | 189 | } // namespace internal 190 | 191 | template struct is_tuple_like { 192 | static FMT_CONSTEXPR_DECL const bool value = 193 | internal::is_tuple_like_::value && !internal::is_range_::value; 194 | }; 195 | 196 | template 197 | struct formatter::value>> { 198 | private: 199 | // C++11 generic lambda for format() 200 | template struct format_each { 201 | template void operator()(const T& v) { 202 | if (i > 0) { 203 | if (formatting.add_prepostfix_space) { 204 | *out++ = ' '; 205 | } 206 | out = internal::copy(formatting.delimiter, out); 207 | } 208 | out = format_to(out, 209 | internal::format_str_quoted( 210 | (formatting.add_delimiter_spaces && i > 0), v), 211 | v); 212 | ++i; 213 | } 214 | 215 | formatting_tuple& formatting; 216 | std::size_t& i; 217 | typename std::add_lvalue_reference().out())>::type out; 219 | }; 220 | 221 | public: 222 | formatting_tuple formatting; 223 | 224 | template 225 | FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { 226 | return formatting.parse(ctx); 227 | } 228 | 229 | template 230 | auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) { 231 | auto out = ctx.out(); 232 | std::size_t i = 0; 233 | internal::copy(formatting.prefix, out); 234 | 235 | internal::for_each(values, format_each{formatting, i, out}); 236 | if (formatting.add_prepostfix_space) { 237 | *out++ = ' '; 238 | } 239 | internal::copy(formatting.postfix, out); 240 | 241 | return ctx.out(); 242 | } 243 | }; 244 | 245 | template struct is_range { 246 | static FMT_CONSTEXPR_DECL const bool value = 247 | internal::is_range_::value && 248 | !internal::is_like_std_string::value && 249 | !std::is_convertible>::value; 250 | }; 251 | 252 | template 253 | struct formatter::value>> { 255 | formatting_range formatting; 256 | 257 | template 258 | FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { 259 | return formatting.parse(ctx); 260 | } 261 | 262 | template 263 | typename FormatContext::iterator format(const RangeT& values, 264 | FormatContext& ctx) { 265 | auto out = internal::copy(formatting.prefix, ctx.out()); 266 | std::size_t i = 0; 267 | for (auto it = values.begin(), end = values.end(); it != end; ++it) { 268 | if (i > 0) { 269 | if (formatting.add_prepostfix_space) *out++ = ' '; 270 | out = internal::copy(formatting.delimiter, out); 271 | } 272 | out = format_to(out, 273 | internal::format_str_quoted( 274 | (formatting.add_delimiter_spaces && i > 0), *it), 275 | *it); 276 | if (++i > formatting.range_length_limit) { 277 | out = format_to(out, " ... "); 278 | break; 279 | } 280 | } 281 | if (formatting.add_prepostfix_space) *out++ = ' '; 282 | return internal::copy(formatting.postfix, out); 283 | } 284 | }; 285 | 286 | FMT_END_NAMESPACE 287 | 288 | #endif // FMT_RANGES_H_ 289 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/fmt.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2016-2018 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | 8 | // 9 | // Include a bundled header-only copy of fmtlib or an external one. 10 | // By default spdlog include its own copy. 11 | // 12 | 13 | #if !defined(SPDLOG_FMT_EXTERNAL) 14 | #ifdef SPDLOG_HEADER_ONLY 15 | #ifndef FMT_HEADER_ONLY 16 | #define FMT_HEADER_ONLY 17 | #endif 18 | #endif 19 | #ifndef FMT_USE_WINDOWS_H 20 | #define FMT_USE_WINDOWS_H 0 21 | #endif 22 | #include "bundled/core.h" 23 | #include "bundled/format.h" 24 | #else // SPDLOG_FMT_EXTERNAL is defined - use external fmtlib 25 | #include "fmt/core.h" 26 | #include "fmt/format.h" 27 | #endif 28 | -------------------------------------------------------------------------------- /includes/spdlog/fmt/ostr.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright(c) 2016 Gabi Melman. 3 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 4 | // 5 | 6 | #pragma once 7 | // 8 | // include bundled or external copy of fmtlib's ostream support 9 | // 10 | #if !defined(SPDLOG_FMT_EXTERNAL) 11 | #ifndef FMT_HEADER_ONLY 12 | #define FMT_HEADER_ONLY 13 | #endif 14 | #include "bundled/ostream.h" 15 | #include "fmt.h" 16 | #else 17 | #include 18 | #endif 19 | -------------------------------------------------------------------------------- /includes/spdlog/formatter.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "fmt/fmt.h" 7 | #include "spdlog/details/log_msg.h" 8 | 9 | namespace spdlog { 10 | 11 | class formatter 12 | { 13 | public: 14 | virtual ~formatter() = default; 15 | virtual void format(const details::log_msg &msg, memory_buf_t &dest) = 0; 16 | virtual std::unique_ptr clone() const = 0; 17 | }; 18 | } // namespace spdlog 19 | -------------------------------------------------------------------------------- /includes/spdlog/logger-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/logger.h" 8 | #endif 9 | 10 | #include "spdlog/sinks/sink.h" 11 | #include "spdlog/details/backtracer.h" 12 | #include "spdlog/details/pattern_formatter.h" 13 | 14 | #include 15 | 16 | namespace spdlog { 17 | 18 | // public methods 19 | SPDLOG_INLINE logger::logger(const logger &other) 20 | : name_(other.name_) 21 | , sinks_(other.sinks_) 22 | , level_(other.level_.load(std::memory_order_relaxed)) 23 | , flush_level_(other.flush_level_.load(std::memory_order_relaxed)) 24 | , custom_err_handler_(other.custom_err_handler_) 25 | , tracer_(other.tracer_) 26 | {} 27 | 28 | SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT : name_(std::move(other.name_)), 29 | sinks_(std::move(other.sinks_)), 30 | level_(other.level_.load(std::memory_order_relaxed)), 31 | flush_level_(other.flush_level_.load(std::memory_order_relaxed)), 32 | custom_err_handler_(std::move(other.custom_err_handler_)), 33 | tracer_(std::move(other.tracer_)) 34 | 35 | {} 36 | 37 | SPDLOG_INLINE logger &logger::operator=(logger other) SPDLOG_NOEXCEPT 38 | { 39 | this->swap(other); 40 | return *this; 41 | } 42 | 43 | SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT 44 | { 45 | name_.swap(other.name_); 46 | sinks_.swap(other.sinks_); 47 | 48 | // swap level_ 49 | auto other_level = other.level_.load(); 50 | auto my_level = level_.exchange(other_level); 51 | other.level_.store(my_level); 52 | 53 | // swap flush level_ 54 | other_level = other.flush_level_.load(); 55 | my_level = flush_level_.exchange(other_level); 56 | other.flush_level_.store(my_level); 57 | 58 | custom_err_handler_.swap(other.custom_err_handler_); 59 | std::swap(tracer_, other.tracer_); 60 | } 61 | 62 | SPDLOG_INLINE void swap(logger &a, logger &b) 63 | { 64 | a.swap(b); 65 | } 66 | 67 | SPDLOG_INLINE bool logger::should_log(level::level_enum msg_level) const 68 | { 69 | return msg_level >= level_.load(std::memory_order_relaxed); 70 | } 71 | 72 | SPDLOG_INLINE void logger::set_level(level::level_enum log_level) 73 | { 74 | level_.store(log_level); 75 | } 76 | 77 | SPDLOG_INLINE level::level_enum logger::level() const 78 | { 79 | return static_cast(level_.load(std::memory_order_relaxed)); 80 | } 81 | 82 | SPDLOG_INLINE const std::string &logger::name() const 83 | { 84 | return name_; 85 | } 86 | 87 | // set formatting for the sinks in this logger. 88 | // each sink will get a seperate instance of the formatter object. 89 | SPDLOG_INLINE void logger::set_formatter(std::unique_ptr f) 90 | { 91 | for (auto it = sinks_.begin(); it != sinks_.end(); ++it) 92 | { 93 | if (std::next(it) == sinks_.end()) 94 | { 95 | // last element - we can be move it. 96 | (*it)->set_formatter(std::move(f)); 97 | } 98 | else 99 | { 100 | (*it)->set_formatter(f->clone()); 101 | } 102 | } 103 | } 104 | 105 | SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type time_type) 106 | { 107 | auto new_formatter = details::make_unique(std::move(pattern), time_type); 108 | set_formatter(std::move(new_formatter)); 109 | } 110 | 111 | // create new backtrace sink and move to it all our child sinks 112 | SPDLOG_INLINE void logger::enable_backtrace(size_t n_messages) 113 | { 114 | tracer_.enable(n_messages); 115 | } 116 | 117 | // restore orig sinks and level and delete the backtrace sink 118 | SPDLOG_INLINE void logger::disable_backtrace() 119 | { 120 | tracer_.disable(); 121 | } 122 | 123 | SPDLOG_INLINE void logger::dump_backtrace() 124 | { 125 | dump_backtrace_(); 126 | } 127 | 128 | // flush functions 129 | SPDLOG_INLINE void logger::flush() 130 | { 131 | flush_(); 132 | } 133 | 134 | SPDLOG_INLINE void logger::flush_on(level::level_enum log_level) 135 | { 136 | flush_level_.store(log_level); 137 | } 138 | 139 | SPDLOG_INLINE level::level_enum logger::flush_level() const 140 | { 141 | return static_cast(flush_level_.load(std::memory_order_relaxed)); 142 | } 143 | 144 | // sinks 145 | SPDLOG_INLINE const std::vector &logger::sinks() const 146 | { 147 | return sinks_; 148 | } 149 | 150 | SPDLOG_INLINE std::vector &logger::sinks() 151 | { 152 | return sinks_; 153 | } 154 | 155 | // error handler 156 | SPDLOG_INLINE void logger::set_error_handler(err_handler handler) 157 | { 158 | custom_err_handler_ = handler; 159 | } 160 | 161 | // create new logger with same sinks and configuration. 162 | SPDLOG_INLINE std::shared_ptr logger::clone(std::string logger_name) 163 | { 164 | auto cloned = std::make_shared(*this); 165 | cloned->name_ = std::move(logger_name); 166 | return cloned; 167 | } 168 | 169 | // protected methods 170 | SPDLOG_INLINE void logger::sink_it_(const details::log_msg &msg) 171 | { 172 | for (auto &sink : sinks_) 173 | { 174 | if (sink->should_log(msg.level)) 175 | { 176 | SPDLOG_TRY 177 | { 178 | sink->log(msg); 179 | } 180 | SPDLOG_LOGGER_CATCH() 181 | } 182 | } 183 | 184 | if (should_flush_(msg)) 185 | { 186 | flush_(); 187 | } 188 | } 189 | 190 | SPDLOG_INLINE void logger::flush_() 191 | { 192 | for (auto &sink : sinks_) 193 | { 194 | SPDLOG_TRY 195 | { 196 | sink->flush(); 197 | } 198 | SPDLOG_LOGGER_CATCH() 199 | } 200 | } 201 | 202 | SPDLOG_INLINE void logger::dump_backtrace_() 203 | { 204 | using details::log_msg; 205 | if (tracer_) 206 | { 207 | sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"}); 208 | tracer_.foreach_pop([this](const details::log_msg &msg) { this->sink_it_(msg); }); 209 | sink_it_(log_msg{name(), level::info, "****************** Backtrace End ********************"}); 210 | } 211 | } 212 | 213 | SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) 214 | { 215 | auto flush_level = flush_level_.load(std::memory_order_relaxed); 216 | return (msg.level >= flush_level) && (msg.level != level::off); 217 | } 218 | 219 | SPDLOG_INLINE void logger::err_handler_(const std::string &msg) 220 | { 221 | 222 | if (custom_err_handler_) 223 | { 224 | custom_err_handler_(msg); 225 | } 226 | else 227 | { 228 | using std::chrono::system_clock; 229 | static std::mutex mutex; 230 | static std::chrono::system_clock::time_point last_report_time; 231 | static size_t err_counter = 0; 232 | std::lock_guard lk{mutex}; 233 | auto now = system_clock::now(); 234 | err_counter++; 235 | if (now - last_report_time < std::chrono::seconds(1)) 236 | { 237 | return; 238 | } 239 | last_report_time = now; 240 | auto tm_time = details::os::localtime(system_clock::to_time_t(now)); 241 | char date_buf[64]; 242 | std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time); 243 | fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] {%s}\n", err_counter, date_buf, name().c_str(), msg.c_str()); 244 | } 245 | } 246 | } // namespace spdlog 247 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/android_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifdef __ANDROID__ 7 | 8 | #include "spdlog/details/fmt_helper.h" 9 | #include "spdlog/details/null_mutex.h" 10 | #include "spdlog/details/os.h" 11 | #include "spdlog/sinks/base_sink.h" 12 | #include "spdlog/details/synchronous_factory.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #if !defined(SPDLOG_ANDROID_RETRIES) 21 | #define SPDLOG_ANDROID_RETRIES 2 22 | #endif 23 | 24 | namespace spdlog { 25 | namespace sinks { 26 | 27 | /* 28 | * Android sink (logging using __android_log_write) 29 | */ 30 | template 31 | class android_sink final : public base_sink 32 | { 33 | public: 34 | explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false) 35 | : tag_(std::move(tag)) 36 | , use_raw_msg_(use_raw_msg) 37 | {} 38 | 39 | protected: 40 | void sink_it_(const details::log_msg &msg) override 41 | { 42 | const android_LogPriority priority = convert_to_android_(msg.level); 43 | memory_buf_t formatted; 44 | if (use_raw_msg_) 45 | { 46 | details::fmt_helper::append_string_view(msg.payload, formatted); 47 | } 48 | else 49 | { 50 | base_sink::formatter_->format(msg, formatted); 51 | } 52 | formatted.push_back('\0'); 53 | const char *msg_output = formatted.data(); 54 | 55 | // See system/core/liblog/logger_write.c for explanation of return value 56 | int ret = __android_log_write(priority, tag_.c_str(), msg_output); 57 | int retry_count = 0; 58 | while ((ret == -11 /*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES)) 59 | { 60 | details::os::sleep_for_millis(5); 61 | ret = __android_log_write(priority, tag_.c_str(), msg_output); 62 | retry_count++; 63 | } 64 | 65 | if (ret < 0) 66 | { 67 | SPDLOG_THROW(spdlog_ex("__android_log_write() failed", ret)); 68 | } 69 | } 70 | 71 | void flush_() override {} 72 | 73 | private: 74 | static android_LogPriority convert_to_android_(spdlog::level::level_enum level) 75 | { 76 | switch (level) 77 | { 78 | case spdlog::level::trace: 79 | return ANDROID_LOG_VERBOSE; 80 | case spdlog::level::debug: 81 | return ANDROID_LOG_DEBUG; 82 | case spdlog::level::info: 83 | return ANDROID_LOG_INFO; 84 | case spdlog::level::warn: 85 | return ANDROID_LOG_WARN; 86 | case spdlog::level::err: 87 | return ANDROID_LOG_ERROR; 88 | case spdlog::level::critical: 89 | return ANDROID_LOG_FATAL; 90 | default: 91 | return ANDROID_LOG_DEFAULT; 92 | } 93 | } 94 | 95 | std::string tag_; 96 | bool use_raw_msg_; 97 | }; 98 | 99 | using android_sink_mt = android_sink; 100 | using android_sink_st = android_sink; 101 | } // namespace sinks 102 | 103 | // Create and register android syslog logger 104 | 105 | template 106 | inline std::shared_ptr android_logger_mt(const std::string &logger_name, const std::string &tag = "spdlog") 107 | { 108 | return Factory::template create(logger_name, tag); 109 | } 110 | 111 | template 112 | inline std::shared_ptr android_logger_st(const std::string &logger_name, const std::string &tag = "spdlog") 113 | { 114 | return Factory::template create(logger_name, tag); 115 | } 116 | 117 | } // namespace spdlog 118 | 119 | #endif // __ANDROID__ -------------------------------------------------------------------------------- /includes/spdlog/sinks/ansicolor_sink-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/ansicolor_sink.h" 8 | #endif 9 | 10 | #include "spdlog/details/pattern_formatter.h" 11 | #include "spdlog/details/os.h" 12 | 13 | namespace spdlog { 14 | namespace sinks { 15 | 16 | template 17 | SPDLOG_INLINE ansicolor_sink::ansicolor_sink(FILE *target_file, color_mode mode) 18 | : target_file_(target_file) 19 | , mutex_(ConsoleMutex::mutex()) 20 | , formatter_(details::make_unique()) 21 | 22 | { 23 | set_color_mode(mode); 24 | colors_[level::trace] = white; 25 | colors_[level::debug] = cyan; 26 | colors_[level::info] = green; 27 | colors_[level::warn] = yellow_bold; 28 | colors_[level::err] = red_bold; 29 | colors_[level::critical] = bold_on_red; 30 | colors_[level::off] = reset; 31 | } 32 | 33 | template 34 | SPDLOG_INLINE void ansicolor_sink::set_color(level::level_enum color_level, string_view_t color) 35 | { 36 | std::lock_guard lock(mutex_); 37 | colors_[color_level] = color; 38 | } 39 | 40 | template 41 | SPDLOG_INLINE void ansicolor_sink::log(const details::log_msg &msg) 42 | { 43 | // Wrap the originally formatted message in color codes. 44 | // If color is not supported in the terminal, log as is instead. 45 | std::lock_guard lock(mutex_); 46 | 47 | memory_buf_t formatted; 48 | formatter_->format(msg, formatted); 49 | if (should_do_colors_ && msg.color_range_end > msg.color_range_start) 50 | { 51 | // before color range 52 | print_range_(formatted, 0, msg.color_range_start); 53 | // in color range 54 | print_ccode_(colors_[msg.level]); 55 | print_range_(formatted, msg.color_range_start, msg.color_range_end); 56 | print_ccode_(reset); 57 | // after color range 58 | print_range_(formatted, msg.color_range_end, formatted.size()); 59 | } 60 | else // no color 61 | { 62 | print_range_(formatted, 0, formatted.size()); 63 | } 64 | fflush(target_file_); 65 | } 66 | 67 | template 68 | SPDLOG_INLINE void ansicolor_sink::flush() 69 | { 70 | std::lock_guard lock(mutex_); 71 | fflush(target_file_); 72 | } 73 | 74 | template 75 | SPDLOG_INLINE void ansicolor_sink::set_pattern(const std::string &pattern) 76 | { 77 | std::lock_guard lock(mutex_); 78 | formatter_ = std::unique_ptr(new pattern_formatter(pattern)); 79 | } 80 | 81 | template 82 | SPDLOG_INLINE void ansicolor_sink::set_formatter(std::unique_ptr sink_formatter) 83 | { 84 | std::lock_guard lock(mutex_); 85 | formatter_ = std::move(sink_formatter); 86 | } 87 | 88 | template 89 | SPDLOG_INLINE bool ansicolor_sink::should_color() 90 | { 91 | return should_do_colors_; 92 | } 93 | 94 | template 95 | SPDLOG_INLINE void ansicolor_sink::set_color_mode(color_mode mode) 96 | { 97 | switch (mode) 98 | { 99 | case color_mode::always: 100 | should_do_colors_ = true; 101 | return; 102 | case color_mode::automatic: 103 | should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal(); 104 | return; 105 | case color_mode::never: 106 | should_do_colors_ = false; 107 | return; 108 | } 109 | } 110 | 111 | template 112 | SPDLOG_INLINE void ansicolor_sink::print_ccode_(const string_view_t &color_code) 113 | { 114 | fwrite(color_code.data(), sizeof(string_view_t::char_type), color_code.size(), target_file_); 115 | } 116 | 117 | template 118 | SPDLOG_INLINE void ansicolor_sink::print_range_(const memory_buf_t &formatted, size_t start, size_t end) 119 | { 120 | fwrite(formatted.data() + start, sizeof(char), end - start, target_file_); 121 | } 122 | 123 | // ansicolor_stdout_sink 124 | template 125 | SPDLOG_INLINE ansicolor_stdout_sink::ansicolor_stdout_sink(color_mode mode) 126 | : ansicolor_sink(stdout, mode) 127 | {} 128 | 129 | // ansicolor_stderr_sink 130 | template 131 | SPDLOG_INLINE ansicolor_stderr_sink::ansicolor_stderr_sink(color_mode mode) 132 | : ansicolor_sink(stderr, mode) 133 | {} 134 | 135 | } // namespace sinks 136 | } // namespace spdlog 137 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/ansicolor_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/console_globals.h" 7 | #include "spdlog/details/null_mutex.h" 8 | #include "spdlog/sinks/sink.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace spdlog { 15 | namespace sinks { 16 | 17 | /** 18 | * This sink prefixes the output with an ANSI escape sequence color code 19 | * depending on the severity 20 | * of the message. 21 | * If no color terminal detected, omit the escape codes. 22 | */ 23 | 24 | template 25 | class ansicolor_sink : public sink 26 | { 27 | public: 28 | using mutex_t = typename ConsoleMutex::mutex_t; 29 | ansicolor_sink(FILE *target_file, color_mode mode); 30 | ~ansicolor_sink() override = default; 31 | 32 | ansicolor_sink(const ansicolor_sink &other) = delete; 33 | ansicolor_sink &operator=(const ansicolor_sink &other) = delete; 34 | void set_color(level::level_enum color_level, string_view_t color); 35 | void set_color_mode(color_mode mode); 36 | bool should_color(); 37 | 38 | void log(const details::log_msg &msg) override; 39 | void flush() override; 40 | void set_pattern(const std::string &pattern) final; 41 | void set_formatter(std::unique_ptr sink_formatter) override; 42 | 43 | // Formatting codes 44 | const string_view_t reset = "\033[m"; 45 | const string_view_t bold = "\033[1m"; 46 | const string_view_t dark = "\033[2m"; 47 | const string_view_t underline = "\033[4m"; 48 | const string_view_t blink = "\033[5m"; 49 | const string_view_t reverse = "\033[7m"; 50 | const string_view_t concealed = "\033[8m"; 51 | const string_view_t clear_line = "\033[K"; 52 | 53 | // Foreground colors 54 | const string_view_t black = "\033[30m"; 55 | const string_view_t red = "\033[31m"; 56 | const string_view_t green = "\033[32m"; 57 | const string_view_t yellow = "\033[33m"; 58 | const string_view_t blue = "\033[34m"; 59 | const string_view_t magenta = "\033[35m"; 60 | const string_view_t cyan = "\033[36m"; 61 | const string_view_t white = "\033[37m"; 62 | 63 | /// Background colors 64 | const string_view_t on_black = "\033[40m"; 65 | const string_view_t on_red = "\033[41m"; 66 | const string_view_t on_green = "\033[42m"; 67 | const string_view_t on_yellow = "\033[43m"; 68 | const string_view_t on_blue = "\033[44m"; 69 | const string_view_t on_magenta = "\033[45m"; 70 | const string_view_t on_cyan = "\033[46m"; 71 | const string_view_t on_white = "\033[47m"; 72 | 73 | /// Bold colors 74 | const string_view_t yellow_bold = "\033[33m\033[1m"; 75 | const string_view_t red_bold = "\033[31m\033[1m"; 76 | const string_view_t bold_on_red = "\033[1m\033[41m"; 77 | 78 | private: 79 | FILE *target_file_; 80 | mutex_t &mutex_; 81 | bool should_do_colors_; 82 | std::unique_ptr formatter_; 83 | std::unordered_map colors_; 84 | void print_ccode_(const string_view_t &color_code); 85 | void print_range_(const memory_buf_t &formatted, size_t start, size_t end); 86 | }; 87 | 88 | template 89 | class ansicolor_stdout_sink : public ansicolor_sink 90 | { 91 | public: 92 | explicit ansicolor_stdout_sink(color_mode mode = color_mode::automatic); 93 | }; 94 | 95 | template 96 | class ansicolor_stderr_sink : public ansicolor_sink 97 | { 98 | public: 99 | explicit ansicolor_stderr_sink(color_mode mode = color_mode::automatic); 100 | }; 101 | 102 | using ansicolor_stdout_sink_mt = ansicolor_stdout_sink; 103 | using ansicolor_stdout_sink_st = ansicolor_stdout_sink; 104 | 105 | using ansicolor_stderr_sink_mt = ansicolor_stderr_sink; 106 | using ansicolor_stderr_sink_st = ansicolor_stderr_sink; 107 | 108 | } // namespace sinks 109 | } // namespace spdlog 110 | 111 | #ifdef SPDLOG_HEADER_ONLY 112 | #include "ansicolor_sink-inl.h" 113 | #endif 114 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/base_sink-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/base_sink.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | #include "spdlog/details/pattern_formatter.h" 12 | 13 | #include 14 | 15 | template 16 | SPDLOG_INLINE spdlog::sinks::base_sink::base_sink() 17 | : formatter_{details::make_unique()} 18 | {} 19 | 20 | template 21 | SPDLOG_INLINE spdlog::sinks::base_sink::base_sink(std::unique_ptr formatter) 22 | : formatter_{std::move(formatter)} 23 | {} 24 | 25 | template 26 | void SPDLOG_INLINE spdlog::sinks::base_sink::log(const details::log_msg &msg) 27 | { 28 | std::lock_guard lock(mutex_); 29 | sink_it_(msg); 30 | } 31 | 32 | template 33 | void SPDLOG_INLINE spdlog::sinks::base_sink::flush() 34 | { 35 | std::lock_guard lock(mutex_); 36 | flush_(); 37 | } 38 | 39 | template 40 | void SPDLOG_INLINE spdlog::sinks::base_sink::set_pattern(const std::string &pattern) 41 | { 42 | std::lock_guard lock(mutex_); 43 | set_pattern_(pattern); 44 | } 45 | 46 | template 47 | void SPDLOG_INLINE spdlog::sinks::base_sink::set_formatter(std::unique_ptr sink_formatter) 48 | { 49 | std::lock_guard lock(mutex_); 50 | set_formatter_(std::move(sink_formatter)); 51 | } 52 | 53 | template 54 | void SPDLOG_INLINE spdlog::sinks::base_sink::set_pattern_(const std::string &pattern) 55 | { 56 | set_formatter_(details::make_unique(pattern)); 57 | } 58 | 59 | template 60 | void SPDLOG_INLINE spdlog::sinks::base_sink::set_formatter_(std::unique_ptr sink_formatter) 61 | { 62 | formatter_ = std::move(sink_formatter); 63 | } 64 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/base_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | // 6 | // base sink templated over a mutex (either dummy or real) 7 | // concrete implementation should override the sink_it_() and flush_() methods. 8 | // locking is taken care of in this class - no locking needed by the 9 | // implementers.. 10 | // 11 | 12 | #include "spdlog/common.h" 13 | #include "spdlog/details/log_msg.h" 14 | #include "spdlog/sinks/sink.h" 15 | 16 | namespace spdlog { 17 | namespace sinks { 18 | template 19 | class base_sink : public sink 20 | { 21 | public: 22 | base_sink(); 23 | explicit base_sink(std::unique_ptr formatter); 24 | base_sink(const base_sink &) = delete; 25 | base_sink &operator=(const base_sink &) = delete; 26 | void log(const details::log_msg &msg) final; 27 | void flush() final; 28 | void set_pattern(const std::string &pattern) final; 29 | void set_formatter(std::unique_ptr sink_formatter) final; 30 | 31 | protected: 32 | // sink formatter 33 | std::unique_ptr formatter_; 34 | Mutex mutex_; 35 | 36 | virtual void sink_it_(const details::log_msg &msg) = 0; 37 | virtual void flush_() = 0; 38 | virtual void set_pattern_(const std::string &pattern); 39 | virtual void set_formatter_(std::unique_ptr sink_formatter); 40 | }; 41 | } // namespace sinks 42 | } // namespace spdlog 43 | 44 | #ifdef SPDLOG_HEADER_ONLY 45 | #include "base_sink-inl.h" 46 | #endif 47 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/basic_file_sink-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/basic_file_sink.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | #include "spdlog/details/os.h" 12 | 13 | namespace spdlog { 14 | namespace sinks { 15 | 16 | template 17 | SPDLOG_INLINE basic_file_sink::basic_file_sink(const filename_t &filename, bool truncate) 18 | { 19 | file_helper_.open(filename, truncate); 20 | } 21 | 22 | template 23 | SPDLOG_INLINE const filename_t &basic_file_sink::filename() const 24 | { 25 | return file_helper_.filename(); 26 | } 27 | 28 | template 29 | SPDLOG_INLINE void basic_file_sink::sink_it_(const details::log_msg &msg) 30 | { 31 | memory_buf_t formatted; 32 | base_sink::formatter_->format(msg, formatted); 33 | file_helper_.write(formatted); 34 | } 35 | 36 | template 37 | SPDLOG_INLINE void basic_file_sink::flush_() 38 | { 39 | file_helper_.flush(); 40 | } 41 | 42 | } // namespace sinks 43 | } // namespace spdlog 44 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/basic_file_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/file_helper.h" 7 | #include "spdlog/details/null_mutex.h" 8 | #include "spdlog/sinks/base_sink.h" 9 | #include "spdlog/details/synchronous_factory.h" 10 | 11 | #include 12 | #include 13 | 14 | namespace spdlog { 15 | namespace sinks { 16 | /* 17 | * Trivial file sink with single file as target 18 | */ 19 | template 20 | class basic_file_sink final : public base_sink 21 | { 22 | public: 23 | explicit basic_file_sink(const filename_t &filename, bool truncate = false); 24 | const filename_t &filename() const; 25 | 26 | protected: 27 | void sink_it_(const details::log_msg &msg) override; 28 | void flush_() override; 29 | 30 | private: 31 | details::file_helper file_helper_; 32 | }; 33 | 34 | using basic_file_sink_mt = basic_file_sink; 35 | using basic_file_sink_st = basic_file_sink; 36 | 37 | } // namespace sinks 38 | 39 | // 40 | // factory functions 41 | // 42 | template 43 | inline std::shared_ptr basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false) 44 | { 45 | return Factory::template create(logger_name, filename, truncate); 46 | } 47 | 48 | template 49 | inline std::shared_ptr basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false) 50 | { 51 | return Factory::template create(logger_name, filename, truncate); 52 | } 53 | 54 | } // namespace spdlog 55 | 56 | #ifdef SPDLOG_HEADER_ONLY 57 | #include "basic_file_sink-inl.h" 58 | #endif -------------------------------------------------------------------------------- /includes/spdlog/sinks/daily_file_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/common.h" 7 | #include "spdlog/details/file_helper.h" 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/fmt/fmt.h" 10 | #include "spdlog/sinks/base_sink.h" 11 | #include "spdlog/details/os.h" 12 | #include "spdlog/details/synchronous_factory.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace spdlog { 21 | namespace sinks { 22 | 23 | /* 24 | * Generator of daily log file names in format basename.YYYY-MM-DD.ext 25 | */ 26 | struct daily_filename_calculator 27 | { 28 | // Create filename for the form basename.YYYY-MM-DD 29 | static filename_t calc_filename(const filename_t &filename, const tm &now_tm) 30 | { 31 | filename_t basename, ext; 32 | std::tie(basename, ext) = details::file_helper::split_by_extension(filename); 33 | return fmt::format( 34 | SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}{}"), basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday, ext); 35 | } 36 | }; 37 | 38 | /* 39 | * Rotating file sink based on date. rotates at midnight 40 | */ 41 | template 42 | class daily_file_sink final : public base_sink 43 | { 44 | public: 45 | // create daily file sink which rotates on given time 46 | daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute, bool truncate = false) 47 | : base_filename_(std::move(base_filename)) 48 | , rotation_h_(rotation_hour) 49 | , rotation_m_(rotation_minute) 50 | , truncate_(truncate) 51 | { 52 | if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59) 53 | { 54 | SPDLOG_THROW(spdlog_ex("daily_file_sink: Invalid rotation time in ctor")); 55 | } 56 | auto now = log_clock::now(); 57 | file_helper_.open(FileNameCalc::calc_filename(base_filename_, now_tm(now)), truncate_); 58 | rotation_tp_ = next_rotation_tp_(); 59 | } 60 | 61 | const filename_t &filename() const 62 | { 63 | return file_helper_.filename(); 64 | } 65 | 66 | protected: 67 | void sink_it_(const details::log_msg &msg) override 68 | { 69 | #ifdef SPDLOG_NO_DATETIME 70 | auto time = log_clock::now(); 71 | #else 72 | auto time = msg.time; 73 | #endif 74 | if (time >= rotation_tp_) 75 | { 76 | file_helper_.open(FileNameCalc::calc_filename(base_filename_, now_tm(time)), truncate_); 77 | rotation_tp_ = next_rotation_tp_(); 78 | } 79 | memory_buf_t formatted; 80 | base_sink::formatter_->format(msg, formatted); 81 | file_helper_.write(formatted); 82 | } 83 | 84 | void flush_() override 85 | { 86 | file_helper_.flush(); 87 | } 88 | 89 | private: 90 | tm now_tm(log_clock::time_point tp) 91 | { 92 | time_t tnow = log_clock::to_time_t(tp); 93 | return spdlog::details::os::localtime(tnow); 94 | } 95 | 96 | log_clock::time_point next_rotation_tp_() 97 | { 98 | auto now = log_clock::now(); 99 | tm date = now_tm(now); 100 | date.tm_hour = rotation_h_; 101 | date.tm_min = rotation_m_; 102 | date.tm_sec = 0; 103 | auto rotation_time = log_clock::from_time_t(std::mktime(&date)); 104 | if (rotation_time > now) 105 | { 106 | return rotation_time; 107 | } 108 | return {rotation_time + std::chrono::hours(24)}; 109 | } 110 | 111 | filename_t base_filename_; 112 | int rotation_h_; 113 | int rotation_m_; 114 | log_clock::time_point rotation_tp_; 115 | details::file_helper file_helper_; 116 | bool truncate_; 117 | }; 118 | 119 | using daily_file_sink_mt = daily_file_sink; 120 | using daily_file_sink_st = daily_file_sink; 121 | 122 | } // namespace sinks 123 | 124 | // 125 | // factory functions 126 | // 127 | template 128 | inline std::shared_ptr daily_logger_mt( 129 | const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false) 130 | { 131 | return Factory::template create(logger_name, filename, hour, minute, truncate); 132 | } 133 | 134 | template 135 | inline std::shared_ptr daily_logger_st( 136 | const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false) 137 | { 138 | return Factory::template create(logger_name, filename, hour, minute, truncate); 139 | } 140 | } // namespace spdlog 141 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/dist_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "base_sink.h" 7 | #include "spdlog/details/log_msg.h" 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/details/pattern_formatter.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | // Distribution sink (mux). Stores a vector of sinks which get called when log 17 | // is called 18 | 19 | namespace spdlog { 20 | namespace sinks { 21 | 22 | template 23 | class dist_sink : public base_sink 24 | { 25 | public: 26 | dist_sink() = default; 27 | dist_sink(const dist_sink &) = delete; 28 | dist_sink &operator=(const dist_sink &) = delete; 29 | 30 | void add_sink(std::shared_ptr sink) 31 | { 32 | std::lock_guard lock(base_sink::mutex_); 33 | sinks_.push_back(sink); 34 | } 35 | 36 | void remove_sink(std::shared_ptr sink) 37 | { 38 | std::lock_guard lock(base_sink::mutex_); 39 | sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end()); 40 | } 41 | 42 | void set_sinks(std::vector> sinks) 43 | { 44 | std::lock_guard lock(base_sink::mutex_); 45 | sinks_ = std::move(sinks); 46 | } 47 | 48 | std::vector> &sinks() 49 | { 50 | return sinks_; 51 | } 52 | 53 | protected: 54 | void sink_it_(const details::log_msg &msg) override 55 | { 56 | for (auto &sink : sinks_) 57 | { 58 | if (sink->should_log(msg.level)) 59 | { 60 | sink->log(msg); 61 | } 62 | } 63 | } 64 | 65 | void flush_() override 66 | { 67 | for (auto &sink : sinks_) 68 | { 69 | sink->flush(); 70 | } 71 | } 72 | 73 | void set_pattern_(const std::string &pattern) override 74 | { 75 | set_formatter_(details::make_unique(pattern)); 76 | } 77 | 78 | void set_formatter_(std::unique_ptr sink_formatter) override 79 | { 80 | base_sink::formatter_ = std::move(sink_formatter); 81 | for (auto &sink : sinks_) 82 | { 83 | sink->set_formatter(base_sink::formatter_->clone()); 84 | } 85 | } 86 | std::vector> sinks_; 87 | }; 88 | 89 | using dist_sink_mt = dist_sink; 90 | using dist_sink_st = dist_sink; 91 | 92 | } // namespace sinks 93 | } // namespace spdlog 94 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/dup_filter_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "dist_sink.h" 7 | #include "spdlog/details/null_mutex.h" 8 | #include "spdlog/details/log_msg.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | // Duplicate message removal sink. 15 | // Skip the message if previous one is identical and less than "max_skip_duration" have passed 16 | // 17 | // Example: 18 | // 19 | // #include "spdlog/sinks/dup_filter_sink.h" 20 | // 21 | // int main() { 22 | // auto dup_filter = std::make_shared(std::chrono::seconds(5)); 23 | // dup_filter->add_sink(std::make_shared()); 24 | // spdlog::logger l("logger", dup_filter); 25 | // l.info("Hello"); 26 | // l.info("Hello"); 27 | // l.info("Hello"); 28 | // l.info("Different Hello"); 29 | // } 30 | // 31 | // Will produce: 32 | // [2019-06-25 17:50:56.511] [logger] [info] Hello 33 | // [2019-06-25 17:50:56.512] [logger] [info] Skipped 3 duplicate messages.. 34 | // [2019-06-25 17:50:56.512] [logger] [info] Different Hello 35 | 36 | #ifdef SPDLOG_NO_DATETIME 37 | #error "spdlog::sinks::dup_filter_sink: cannot work when SPDLOG_NO_DATETIME is defined" 38 | #endif 39 | 40 | namespace spdlog { 41 | namespace sinks { 42 | template 43 | class dup_filter_sink : public dist_sink 44 | { 45 | public: 46 | template 47 | explicit dup_filter_sink(std::chrono::duration max_skip_duration) 48 | : max_skip_duration_{max_skip_duration} 49 | {} 50 | 51 | protected: 52 | std::chrono::microseconds max_skip_duration_; 53 | log_clock::time_point last_msg_time_; 54 | std::string last_msg_payload_; 55 | size_t skip_counter_ = 0; 56 | 57 | void sink_it_(const details::log_msg &msg) override 58 | { 59 | bool filtered = filter_(msg); 60 | if (!filtered) 61 | { 62 | skip_counter_ += 1; 63 | return; 64 | } 65 | 66 | // log the "skipped.." message 67 | if (skip_counter_ > 0) 68 | { 69 | memory_buf_t buf; 70 | fmt::format_to(buf, "Skipped {} duplicate messages..", skip_counter_); 71 | details::log_msg skipped_msg{msg.logger_name, msg.level, string_view_t{buf.data(), buf.size()}}; 72 | dist_sink::sink_it_(skipped_msg); 73 | } 74 | 75 | // log current message 76 | dist_sink::sink_it_(msg); 77 | last_msg_time_ = msg.time; 78 | skip_counter_ = 0; 79 | last_msg_payload_.assign(msg.payload.data(), msg.payload.data() + msg.payload.size()); 80 | } 81 | 82 | // return whether the log msg should be displayed (true) or skipped (false) 83 | bool filter_(const details::log_msg &msg) 84 | { 85 | auto filter_duration = msg.time - last_msg_time_; 86 | return (filter_duration > max_skip_duration_) || (msg.payload != last_msg_payload_); 87 | } 88 | }; 89 | 90 | using dup_filter_sink_mt = dup_filter_sink; 91 | using dup_filter_sink_st = dup_filter_sink; 92 | 93 | } // namespace sinks 94 | } // namespace spdlog 95 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/msvc_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2016 Alexander Dalshov. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #if defined(_WIN32) 7 | 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/sinks/base_sink.h" 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace spdlog { 17 | namespace sinks { 18 | /* 19 | * MSVC sink (logging using OutputDebugStringA) 20 | */ 21 | template 22 | class msvc_sink : public base_sink 23 | { 24 | public: 25 | explicit msvc_sink() {} 26 | 27 | protected: 28 | void sink_it_(const details::log_msg &msg) override 29 | { 30 | 31 | memory_buf_t formatted; 32 | base_sink::formatter_->format(msg, formatted); 33 | OutputDebugStringA(fmt::to_string(formatted).c_str()); 34 | } 35 | 36 | void flush_() override {} 37 | }; 38 | 39 | using msvc_sink_mt = msvc_sink; 40 | using msvc_sink_st = msvc_sink; 41 | 42 | using windebug_sink_mt = msvc_sink_mt; 43 | using windebug_sink_st = msvc_sink_st; 44 | 45 | } // namespace sinks 46 | } // namespace spdlog 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/null_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/null_mutex.h" 7 | #include "spdlog/sinks/base_sink.h" 8 | #include "spdlog/details/synchronous_factory.h" 9 | 10 | #include 11 | 12 | namespace spdlog { 13 | namespace sinks { 14 | 15 | template 16 | class null_sink : public base_sink 17 | { 18 | protected: 19 | void sink_it_(const details::log_msg &) override {} 20 | void flush_() override {} 21 | }; 22 | 23 | using null_sink_mt = null_sink; 24 | using null_sink_st = null_sink; 25 | 26 | } // namespace sinks 27 | 28 | template 29 | inline std::shared_ptr null_logger_mt(const std::string &logger_name) 30 | { 31 | auto null_logger = Factory::template create(logger_name); 32 | null_logger->set_level(level::off); 33 | return null_logger; 34 | } 35 | 36 | template 37 | inline std::shared_ptr null_logger_st(const std::string &logger_name) 38 | { 39 | auto null_logger = Factory::template create(logger_name); 40 | null_logger->set_level(level::off); 41 | return null_logger; 42 | } 43 | 44 | } // namespace spdlog 45 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/ostream_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/null_mutex.h" 7 | #include "spdlog/sinks/base_sink.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace spdlog { 13 | namespace sinks { 14 | template 15 | class ostream_sink final : public base_sink 16 | { 17 | public: 18 | explicit ostream_sink(std::ostream &os, bool force_flush = false) 19 | : ostream_(os) 20 | , force_flush_(force_flush) 21 | {} 22 | ostream_sink(const ostream_sink &) = delete; 23 | ostream_sink &operator=(const ostream_sink &) = delete; 24 | 25 | protected: 26 | void sink_it_(const details::log_msg &msg) override 27 | { 28 | memory_buf_t formatted; 29 | base_sink::formatter_->format(msg, formatted); 30 | ostream_.write(formatted.data(), static_cast(formatted.size())); 31 | if (force_flush_) 32 | { 33 | ostream_.flush(); 34 | } 35 | } 36 | 37 | void flush_() override 38 | { 39 | ostream_.flush(); 40 | } 41 | 42 | std::ostream &ostream_; 43 | bool force_flush_; 44 | }; 45 | 46 | using ostream_sink_mt = ostream_sink; 47 | using ostream_sink_st = ostream_sink; 48 | 49 | } // namespace sinks 50 | } // namespace spdlog 51 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/rotating_file_sink-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/rotating_file_sink.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | 12 | #include "spdlog/details/file_helper.h" 13 | #include "spdlog/details/null_mutex.h" 14 | #include "spdlog/fmt/fmt.h" 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace spdlog { 24 | namespace sinks { 25 | 26 | template 27 | SPDLOG_INLINE rotating_file_sink::rotating_file_sink( 28 | filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open) 29 | : base_filename_(std::move(base_filename)) 30 | , max_size_(max_size) 31 | , max_files_(max_files) 32 | { 33 | file_helper_.open(calc_filename(base_filename_, 0)); 34 | current_size_ = file_helper_.size(); // expensive. called only once 35 | if (rotate_on_open && current_size_ > 0) 36 | { 37 | rotate_(); 38 | } 39 | } 40 | 41 | // calc filename according to index and file extension if exists. 42 | // e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt". 43 | template 44 | SPDLOG_INLINE filename_t rotating_file_sink::calc_filename(const filename_t &filename, std::size_t index) 45 | { 46 | if (index == 0u) 47 | { 48 | return filename; 49 | } 50 | 51 | filename_t basename, ext; 52 | std::tie(basename, ext) = details::file_helper::split_by_extension(filename); 53 | return fmt::format(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext); 54 | } 55 | 56 | template 57 | SPDLOG_INLINE const filename_t &rotating_file_sink::filename() const 58 | { 59 | return file_helper_.filename(); 60 | } 61 | 62 | template 63 | SPDLOG_INLINE void rotating_file_sink::sink_it_(const details::log_msg &msg) 64 | { 65 | memory_buf_t formatted; 66 | base_sink::formatter_->format(msg, formatted); 67 | current_size_ += formatted.size(); 68 | if (current_size_ > max_size_) 69 | { 70 | rotate_(); 71 | current_size_ = formatted.size(); 72 | } 73 | file_helper_.write(formatted); 74 | } 75 | 76 | template 77 | SPDLOG_INLINE void rotating_file_sink::flush_() 78 | { 79 | file_helper_.flush(); 80 | } 81 | 82 | // Rotate files: 83 | // log.txt -> log.1.txt 84 | // log.1.txt -> log.2.txt 85 | // log.2.txt -> log.3.txt 86 | // log.3.txt -> delete 87 | template 88 | SPDLOG_INLINE void rotating_file_sink::rotate_() 89 | { 90 | using details::os::filename_to_str; 91 | file_helper_.close(); 92 | for (auto i = max_files_; i > 0; --i) 93 | { 94 | filename_t src = calc_filename(base_filename_, i - 1); 95 | if (!details::file_helper::file_exists(src)) 96 | { 97 | continue; 98 | } 99 | filename_t target = calc_filename(base_filename_, i); 100 | 101 | if (!rename_file(src, target)) 102 | { 103 | // if failed try again after a small delay. 104 | // this is a workaround to a windows issue, where very high rotation 105 | // rates can cause the rename to fail with permission denied (because of antivirus?). 106 | details::os::sleep_for_millis(100); 107 | if (!rename_file(src, target)) 108 | { 109 | file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit! 110 | current_size_ = 0; 111 | SPDLOG_THROW( 112 | spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno)); 113 | } 114 | } 115 | } 116 | file_helper_.reopen(true); 117 | } 118 | 119 | // delete the target if exists, and rename the src file to target 120 | // return true on success, false otherwise. 121 | template 122 | SPDLOG_INLINE bool rotating_file_sink::rename_file(const filename_t &src_filename, const filename_t &target_filename) 123 | { 124 | // try to delete the target file in case it already exists. 125 | (void)details::os::remove(target_filename); 126 | return details::os::rename(src_filename, target_filename) == 0; 127 | } 128 | 129 | } // namespace sinks 130 | } // namespace spdlog 131 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/rotating_file_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/sinks/base_sink.h" 7 | #include "spdlog/details/file_helper.h" 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/details/synchronous_factory.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace spdlog { 16 | namespace sinks { 17 | 18 | // 19 | // Rotating file sink based on size 20 | // 21 | template 22 | class rotating_file_sink final : public base_sink 23 | { 24 | public: 25 | rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false); 26 | static filename_t calc_filename(const filename_t &filename, std::size_t index); 27 | const filename_t &filename() const; 28 | 29 | protected: 30 | void sink_it_(const details::log_msg &msg) override; 31 | void flush_() override; 32 | 33 | private: 34 | // Rotate files: 35 | // log.txt -> log.1.txt 36 | // log.1.txt -> log.2.txt 37 | // log.2.txt -> log.3.txt 38 | // log.3.txt -> delete 39 | void rotate_(); 40 | 41 | // delete the target if exists, and rename the src file to target 42 | // return true on success, false otherwise. 43 | bool rename_file(const filename_t &src_filename, const filename_t &target_filename); 44 | 45 | filename_t base_filename_; 46 | std::size_t max_size_; 47 | std::size_t max_files_; 48 | std::size_t current_size_; 49 | details::file_helper file_helper_; 50 | }; 51 | 52 | using rotating_file_sink_mt = rotating_file_sink; 53 | using rotating_file_sink_st = rotating_file_sink; 54 | 55 | } // namespace sinks 56 | 57 | // 58 | // factory functions 59 | // 60 | 61 | template 62 | inline std::shared_ptr rotating_logger_mt( 63 | const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false) 64 | { 65 | return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); 66 | } 67 | 68 | template 69 | inline std::shared_ptr rotating_logger_st( 70 | const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false) 71 | { 72 | return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); 73 | } 74 | } // namespace spdlog 75 | 76 | #ifdef SPDLOG_HEADER_ONLY 77 | #include "rotating_file_sink-inl.h" 78 | #endif -------------------------------------------------------------------------------- /includes/spdlog/sinks/sink-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/sink.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | 12 | SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg_level) const 13 | { 14 | return msg_level >= level_.load(std::memory_order_relaxed); 15 | } 16 | 17 | SPDLOG_INLINE void spdlog::sinks::sink::set_level(level::level_enum log_level) 18 | { 19 | level_.store(log_level, std::memory_order_relaxed); 20 | } 21 | 22 | SPDLOG_INLINE spdlog::level::level_enum spdlog::sinks::sink::level() const 23 | { 24 | return static_cast(level_.load(std::memory_order_relaxed)); 25 | } 26 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/log_msg.h" 7 | #include "spdlog/formatter.h" 8 | 9 | namespace spdlog { 10 | 11 | namespace sinks { 12 | class sink 13 | { 14 | public: 15 | virtual ~sink() = default; 16 | virtual void log(const details::log_msg &msg) = 0; 17 | virtual void flush() = 0; 18 | virtual void set_pattern(const std::string &pattern) = 0; 19 | virtual void set_formatter(std::unique_ptr sink_formatter) = 0; 20 | 21 | void set_level(level::level_enum log_level); 22 | level::level_enum level() const; 23 | bool should_log(level::level_enum msg_level) const; 24 | 25 | protected: 26 | // sink log level - default is all 27 | level_t level_{level::trace}; 28 | }; 29 | 30 | } // namespace sinks 31 | } // namespace spdlog 32 | 33 | #ifdef SPDLOG_HEADER_ONLY 34 | #include "sink-inl.h" 35 | #endif 36 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/stdout_color_sinks-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/stdout_color_sinks.h" 8 | #endif 9 | 10 | #include "spdlog/logger.h" 11 | #include "spdlog/common.h" 12 | 13 | namespace spdlog { 14 | 15 | template 16 | SPDLOG_INLINE std::shared_ptr stdout_color_mt(const std::string &logger_name, color_mode mode) 17 | { 18 | return Factory::template create(logger_name, mode); 19 | } 20 | 21 | template 22 | SPDLOG_INLINE std::shared_ptr stdout_color_st(const std::string &logger_name, color_mode mode) 23 | { 24 | return Factory::template create(logger_name, mode); 25 | } 26 | 27 | template 28 | SPDLOG_INLINE std::shared_ptr stderr_color_mt(const std::string &logger_name, color_mode mode) 29 | { 30 | return Factory::template create(logger_name, mode); 31 | } 32 | 33 | template 34 | SPDLOG_INLINE std::shared_ptr stderr_color_st(const std::string &logger_name, color_mode mode) 35 | { 36 | return Factory::template create(logger_name, mode); 37 | } 38 | } // namespace spdlog -------------------------------------------------------------------------------- /includes/spdlog/sinks/stdout_color_sinks.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifdef _WIN32 7 | #include "spdlog/sinks/wincolor_sink.h" 8 | #else 9 | #include "spdlog/sinks/ansicolor_sink.h" 10 | #endif 11 | 12 | #include "spdlog/details/synchronous_factory.h" 13 | 14 | namespace spdlog { 15 | namespace sinks { 16 | #ifdef _WIN32 17 | using stdout_color_sink_mt = wincolor_stdout_sink_mt; 18 | using stdout_color_sink_st = wincolor_stdout_sink_st; 19 | using stderr_color_sink_mt = wincolor_stderr_sink_mt; 20 | using stderr_color_sink_st = wincolor_stderr_sink_st; 21 | #else 22 | using stdout_color_sink_mt = ansicolor_stdout_sink_mt; 23 | using stdout_color_sink_st = ansicolor_stdout_sink_st; 24 | using stderr_color_sink_mt = ansicolor_stderr_sink_mt; 25 | using stderr_color_sink_st = ansicolor_stderr_sink_st; 26 | #endif 27 | } // namespace sinks 28 | 29 | template 30 | std::shared_ptr stdout_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic); 31 | 32 | template 33 | std::shared_ptr stdout_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic); 34 | 35 | template 36 | std::shared_ptr stderr_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic); 37 | 38 | template 39 | std::shared_ptr stderr_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic); 40 | 41 | } // namespace spdlog 42 | 43 | #ifdef SPDLOG_HEADER_ONLY 44 | #include "stdout_color_sinks-inl.h" 45 | #endif 46 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/stdout_sinks-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/stdout_sinks.h" 8 | #endif 9 | 10 | #include "spdlog/details/console_globals.h" 11 | #include "spdlog/details/pattern_formatter.h" 12 | #include 13 | 14 | namespace spdlog { 15 | 16 | namespace sinks { 17 | 18 | template 19 | SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) 20 | : mutex_(ConsoleMutex::mutex()) 21 | , file_(file) 22 | , formatter_(details::make_unique()) 23 | {} 24 | 25 | template 26 | SPDLOG_INLINE void stdout_sink_base::log(const details::log_msg &msg) 27 | { 28 | std::lock_guard lock(mutex_); 29 | memory_buf_t formatted; 30 | formatter_->format(msg, formatted); 31 | fwrite(formatted.data(), sizeof(char), formatted.size(), file_); 32 | fflush(file_); // flush every line to terminal 33 | } 34 | 35 | template 36 | SPDLOG_INLINE void stdout_sink_base::flush() 37 | { 38 | std::lock_guard lock(mutex_); 39 | fflush(file_); 40 | } 41 | 42 | template 43 | SPDLOG_INLINE void stdout_sink_base::set_pattern(const std::string &pattern) 44 | { 45 | std::lock_guard lock(mutex_); 46 | formatter_ = std::unique_ptr(new pattern_formatter(pattern)); 47 | } 48 | 49 | template 50 | SPDLOG_INLINE void stdout_sink_base::set_formatter(std::unique_ptr sink_formatter) 51 | { 52 | std::lock_guard lock(mutex_); 53 | formatter_ = std::move(sink_formatter); 54 | } 55 | 56 | // stdout sink 57 | template 58 | SPDLOG_INLINE stdout_sink::stdout_sink() 59 | : stdout_sink_base(stdout) 60 | {} 61 | 62 | // stderr sink 63 | template 64 | SPDLOG_INLINE stderr_sink::stderr_sink() 65 | : stdout_sink_base(stderr) 66 | {} 67 | 68 | } // namespace sinks 69 | 70 | // factory methods 71 | template 72 | SPDLOG_INLINE std::shared_ptr stdout_logger_mt(const std::string &logger_name) 73 | { 74 | return Factory::template create(logger_name); 75 | } 76 | 77 | template 78 | SPDLOG_INLINE std::shared_ptr stdout_logger_st(const std::string &logger_name) 79 | { 80 | return Factory::template create(logger_name); 81 | } 82 | 83 | template 84 | SPDLOG_INLINE std::shared_ptr stderr_logger_mt(const std::string &logger_name) 85 | { 86 | return Factory::template create(logger_name); 87 | } 88 | 89 | template 90 | SPDLOG_INLINE std::shared_ptr stderr_logger_st(const std::string &logger_name) 91 | { 92 | return Factory::template create(logger_name); 93 | } 94 | } // namespace spdlog 95 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/stdout_sinks.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/details/console_globals.h" 7 | #include "spdlog/details/synchronous_factory.h" 8 | #include "spdlog/sinks/sink.h" 9 | #include 10 | 11 | namespace spdlog { 12 | 13 | namespace sinks { 14 | 15 | template 16 | class stdout_sink_base : public sink 17 | { 18 | public: 19 | using mutex_t = typename ConsoleMutex::mutex_t; 20 | explicit stdout_sink_base(FILE *file); 21 | ~stdout_sink_base() override = default; 22 | stdout_sink_base(const stdout_sink_base &other) = delete; 23 | stdout_sink_base &operator=(const stdout_sink_base &other) = delete; 24 | 25 | void log(const details::log_msg &msg) override; 26 | void flush() override; 27 | void set_pattern(const std::string &pattern) override; 28 | 29 | void set_formatter(std::unique_ptr sink_formatter) override; 30 | 31 | protected: 32 | mutex_t &mutex_; 33 | FILE *file_; 34 | std::unique_ptr formatter_; 35 | }; 36 | 37 | template 38 | class stdout_sink : public stdout_sink_base 39 | { 40 | public: 41 | stdout_sink(); 42 | }; 43 | 44 | template 45 | class stderr_sink : public stdout_sink_base 46 | { 47 | public: 48 | stderr_sink(); 49 | }; 50 | 51 | using stdout_sink_mt = stdout_sink; 52 | using stdout_sink_st = stdout_sink; 53 | 54 | using stderr_sink_mt = stderr_sink; 55 | using stderr_sink_st = stderr_sink; 56 | 57 | } // namespace sinks 58 | 59 | // factory methods 60 | template 61 | std::shared_ptr stdout_logger_mt(const std::string &logger_name); 62 | 63 | template 64 | std::shared_ptr stdout_logger_st(const std::string &logger_name); 65 | 66 | template 67 | std::shared_ptr stderr_logger_mt(const std::string &logger_name); 68 | 69 | template 70 | std::shared_ptr stderr_logger_st(const std::string &logger_name); 71 | 72 | } // namespace spdlog 73 | 74 | #ifdef SPDLOG_HEADER_ONLY 75 | #include "stdout_sinks-inl.h" 76 | #endif 77 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/syslog_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/sinks/base_sink.h" 7 | #include "spdlog/details/null_mutex.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace spdlog { 14 | namespace sinks { 15 | /** 16 | * Sink that write to syslog using the `syscall()` library call. 17 | */ 18 | template 19 | class syslog_sink : public base_sink 20 | { 21 | 22 | public: 23 | syslog_sink(std::string ident, int syslog_option, int syslog_facility, bool enable_formatting) 24 | : enable_formatting_{enable_formatting} 25 | , syslog_levels_{/* spdlog::level::trace */ LOG_DEBUG, 26 | /* spdlog::level::debug */ LOG_DEBUG, 27 | /* spdlog::level::info */ LOG_INFO, 28 | /* spdlog::level::warn */ LOG_WARNING, 29 | /* spdlog::level::err */ LOG_ERR, 30 | /* spdlog::level::critical */ LOG_CRIT, 31 | /* spdlog::level::off */ LOG_INFO} 32 | , ident_{std::move(ident)} 33 | { 34 | // set ident to be program name if empty 35 | ::openlog(ident_.empty() ? nullptr : ident_.c_str(), syslog_option, syslog_facility); 36 | } 37 | 38 | ~syslog_sink() override 39 | { 40 | ::closelog(); 41 | } 42 | 43 | syslog_sink(const syslog_sink &) = delete; 44 | syslog_sink &operator=(const syslog_sink &) = delete; 45 | 46 | protected: 47 | void sink_it_(const details::log_msg &msg) override 48 | { 49 | string_view_t payload; 50 | 51 | if (enable_formatting_) 52 | { 53 | memory_buf_t formatted; 54 | base_sink::formatter_->format(msg, formatted); 55 | payload = string_view_t(formatted.data(), formatted.size()); 56 | } 57 | else 58 | { 59 | payload = msg.payload; 60 | } 61 | 62 | size_t length = payload.size(); 63 | // limit to max int 64 | if (length > static_cast(std::numeric_limits::max())) 65 | { 66 | length = static_cast(std::numeric_limits::max()); 67 | } 68 | 69 | ::syslog(syslog_prio_from_level(msg), "%.*s", static_cast(length), payload.data()); 70 | } 71 | 72 | void flush_() override {} 73 | bool enable_formatting_ = false; 74 | 75 | private: 76 | using levels_array = std::array; 77 | levels_array syslog_levels_; 78 | // must store the ident because the man says openlog might use the pointer as 79 | // is and not a string copy 80 | const std::string ident_; 81 | 82 | // 83 | // Simply maps spdlog's log level to syslog priority level. 84 | // 85 | int syslog_prio_from_level(const details::log_msg &msg) const 86 | { 87 | return syslog_levels_.at(static_cast(msg.level)); 88 | } 89 | }; 90 | 91 | using syslog_sink_mt = syslog_sink; 92 | using syslog_sink_st = syslog_sink; 93 | } // namespace sinks 94 | 95 | // Create and register a syslog logger 96 | template 97 | inline std::shared_ptr syslog_logger_mt(const std::string &logger_name, const std::string &syslog_ident = "", int syslog_option = 0, 98 | int syslog_facility = LOG_USER, bool enable_formatting = false) 99 | { 100 | return Factory::template create(logger_name, syslog_ident, syslog_option, syslog_facility, enable_formatting); 101 | } 102 | 103 | template 104 | inline std::shared_ptr syslog_logger_st(const std::string &logger_name, const std::string &syslog_ident = "", int syslog_option = 0, 105 | int syslog_facility = LOG_USER, bool enable_formatting = false) 106 | { 107 | return Factory::template create(logger_name, syslog_ident, syslog_option, syslog_facility, enable_formatting); 108 | } 109 | } // namespace spdlog 110 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/systemd_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2019 ZVYAGIN.Alexander@gmail.com 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/sinks/base_sink.h" 7 | #include "spdlog/details/null_mutex.h" 8 | #include "spdlog/details/synchronous_factory.h" 9 | 10 | #include 11 | 12 | namespace spdlog { 13 | namespace sinks { 14 | 15 | /** 16 | * Sink that write to systemd journal using the `sd_journal_send()` library call. 17 | * 18 | * Locking is not needed, as `sd_journal_send()` itself is thread-safe. 19 | */ 20 | template 21 | class systemd_sink : public base_sink 22 | { 23 | public: 24 | // 25 | systemd_sink() 26 | : syslog_levels_{/* spdlog::level::trace */ LOG_DEBUG, 27 | /* spdlog::level::debug */ LOG_DEBUG, 28 | /* spdlog::level::info */ LOG_INFO, 29 | /* spdlog::level::warn */ LOG_WARNING, 30 | /* spdlog::level::err */ LOG_ERR, 31 | /* spdlog::level::critical */ LOG_CRIT, 32 | /* spdlog::level::off */ LOG_INFO} 33 | {} 34 | 35 | ~systemd_sink() override {} 36 | 37 | systemd_sink(const systemd_sink &) = delete; 38 | systemd_sink &operator=(const systemd_sink &) = delete; 39 | 40 | protected: 41 | using levels_array = std::array; 42 | levels_array syslog_levels_; 43 | 44 | void sink_it_(const details::log_msg &msg) override 45 | { 46 | int err; 47 | 48 | size_t length = msg.payload.size(); 49 | // limit to max int 50 | if (length > static_cast(std::numeric_limits::max())) 51 | { 52 | length = static_cast(std::numeric_limits::max()); 53 | } 54 | 55 | // Do not send source location if not available 56 | if (msg.source.empty()) 57 | { 58 | // Note: function call inside '()' to avoid macro expansion 59 | err = (sd_journal_send)( 60 | "MESSAGE=%.*s", static_cast(length), msg.payload.data(), "PRIORITY=%d", syslog_level(msg.level), nullptr); 61 | } 62 | else 63 | { 64 | err = (sd_journal_send)("MESSAGE=%.*s", static_cast(length), msg.payload.data(), "PRIORITY=%d", syslog_level(msg.level), 65 | "SOURCE_FILE=%s", msg.source.filename, "SOURCE_LINE=%d", msg.source.line, "SOURCE_FUNC=%s", msg.source.funcname, nullptr); 66 | } 67 | 68 | if (err) 69 | { 70 | SPDLOG_THROW(spdlog_ex("Failed writing to systemd", errno)); 71 | } 72 | } 73 | 74 | int syslog_level(level::level_enum l) 75 | { 76 | return syslog_levels_.at(static_cast(l)); 77 | } 78 | 79 | void flush_() override {} 80 | }; 81 | 82 | using systemd_sink_mt = systemd_sink; 83 | using systemd_sink_st = systemd_sink; 84 | } // namespace sinks 85 | 86 | // Create and register a syslog logger 87 | template 88 | inline std::shared_ptr systemd_logger_mt(const std::string &logger_name) 89 | { 90 | return Factory::template create(logger_name); 91 | } 92 | 93 | template 94 | inline std::shared_ptr systemd_logger_st(const std::string &logger_name) 95 | { 96 | return Factory::template create(logger_name); 97 | } 98 | } // namespace spdlog 99 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/wincolor_sink-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/sinks/wincolor_sink.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | #include "spdlog/details/pattern_formatter.h" 12 | 13 | namespace spdlog { 14 | namespace sinks { 15 | 16 | template 17 | SPDLOG_INLINE wincolor_sink::wincolor_sink(HANDLE out_handle, color_mode mode) 18 | : out_handle_(out_handle) 19 | , mutex_(ConsoleMutex::mutex()) 20 | , formatter_(details::make_unique()) 21 | { 22 | // check if out_handle is points to the actual console. 23 | // ::GetConsoleMode() should return 0 if it is redirected or not valid console handle. 24 | DWORD console_mode; 25 | in_console_ = ::GetConsoleMode(out_handle, &console_mode) != 0; 26 | 27 | set_color_mode(mode); 28 | colors_[level::trace] = WHITE; 29 | colors_[level::debug] = CYAN; 30 | colors_[level::info] = GREEN; 31 | colors_[level::warn] = YELLOW | BOLD; 32 | colors_[level::err] = RED | BOLD; // red bold 33 | colors_[level::critical] = BACKGROUND_RED | WHITE | BOLD; // white bold on red background 34 | colors_[level::off] = 0; 35 | } 36 | 37 | template 38 | SPDLOG_INLINE wincolor_sink::~wincolor_sink() 39 | { 40 | this->flush(); 41 | } 42 | 43 | // change the color for the given level 44 | template 45 | void SPDLOG_INLINE wincolor_sink::set_color(level::level_enum level, WORD color) 46 | { 47 | std::lock_guard lock(mutex_); 48 | colors_[level] = color; 49 | } 50 | 51 | template 52 | void SPDLOG_INLINE wincolor_sink::log(const details::log_msg &msg) 53 | { 54 | std::lock_guard lock(mutex_); 55 | memory_buf_t formatted; 56 | formatter_->format(msg, formatted); 57 | if (!in_console_) 58 | { 59 | write_to_file_(formatted); 60 | return; 61 | } 62 | 63 | if (should_do_colors_ && msg.color_range_end > msg.color_range_start) 64 | { 65 | // before color range 66 | print_range_(formatted, 0, msg.color_range_start); 67 | 68 | // in color range 69 | auto orig_attribs = set_foreground_color_(colors_[msg.level]); 70 | print_range_(formatted, msg.color_range_start, msg.color_range_end); 71 | // reset to orig colors 72 | ::SetConsoleTextAttribute(out_handle_, orig_attribs); 73 | print_range_(formatted, msg.color_range_end, formatted.size()); 74 | } 75 | else // print without colors if color range is invalid (or color is disabled) 76 | { 77 | print_range_(formatted, 0, formatted.size()); 78 | } 79 | } 80 | 81 | template 82 | void SPDLOG_INLINE wincolor_sink::flush() 83 | { 84 | // windows console always flushed? 85 | } 86 | 87 | template 88 | void SPDLOG_INLINE wincolor_sink::set_pattern(const std::string &pattern) 89 | { 90 | std::lock_guard lock(mutex_); 91 | formatter_ = std::unique_ptr(new pattern_formatter(pattern)); 92 | } 93 | 94 | template 95 | void SPDLOG_INLINE wincolor_sink::set_formatter(std::unique_ptr sink_formatter) 96 | { 97 | std::lock_guard lock(mutex_); 98 | formatter_ = std::move(sink_formatter); 99 | } 100 | 101 | template 102 | void SPDLOG_INLINE wincolor_sink::set_color_mode(color_mode mode) 103 | { 104 | switch (mode) 105 | { 106 | case color_mode::always: 107 | case color_mode::automatic: 108 | should_do_colors_ = true; 109 | break; 110 | case color_mode::never: 111 | should_do_colors_ = false; 112 | break; 113 | default: 114 | should_do_colors_ = true; 115 | } 116 | } 117 | 118 | // set foreground color and return the orig console attributes (for resetting later) 119 | template 120 | WORD SPDLOG_INLINE wincolor_sink::set_foreground_color_(WORD attribs) 121 | { 122 | CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info; 123 | ::GetConsoleScreenBufferInfo(out_handle_, &orig_buffer_info); 124 | WORD back_color = orig_buffer_info.wAttributes; 125 | // retrieve the current background color 126 | back_color &= static_cast(~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)); 127 | // keep the background color unchanged 128 | ::SetConsoleTextAttribute(out_handle_, attribs | back_color); 129 | return orig_buffer_info.wAttributes; // return orig attribs 130 | } 131 | 132 | // print a range of formatted message to console 133 | template 134 | void SPDLOG_INLINE wincolor_sink::print_range_(const memory_buf_t &formatted, size_t start, size_t end) 135 | { 136 | auto size = static_cast(end - start); 137 | ::WriteConsoleA(out_handle_, formatted.data() + start, size, nullptr, nullptr); 138 | } 139 | 140 | template 141 | void SPDLOG_INLINE wincolor_sink::write_to_file_(const memory_buf_t &formatted) 142 | { 143 | auto size = static_cast(formatted.size()); 144 | if (size == 0) 145 | { 146 | return; 147 | } 148 | 149 | DWORD total_written = 0; 150 | do 151 | { 152 | DWORD bytes_written = 0; 153 | bool ok = ::WriteFile(out_handle_, formatted.data() + total_written, size - total_written, &bytes_written, nullptr) != 0; 154 | if (!ok || bytes_written == 0) 155 | { 156 | SPDLOG_THROW(spdlog_ex("wincolor_sink: write_to_file_ failed. GetLastError(): " + std::to_string(::GetLastError()))); 157 | } 158 | total_written += bytes_written; 159 | } while (total_written < size); 160 | } 161 | 162 | // wincolor_stdout_sink 163 | template 164 | SPDLOG_INLINE wincolor_stdout_sink::wincolor_stdout_sink(color_mode mode) 165 | : wincolor_sink(::GetStdHandle(STD_OUTPUT_HANDLE), mode) 166 | {} 167 | 168 | // wincolor_stderr_sink 169 | template 170 | SPDLOG_INLINE wincolor_stderr_sink::wincolor_stderr_sink(color_mode mode) 171 | : wincolor_sink(::GetStdHandle(STD_ERROR_HANDLE), mode) 172 | {} 173 | 174 | } // namespace sinks 175 | } // namespace spdlog 176 | -------------------------------------------------------------------------------- /includes/spdlog/sinks/wincolor_sink.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #include "spdlog/common.h" 7 | #include "spdlog/details/console_globals.h" 8 | #include "spdlog/details/null_mutex.h" 9 | #include "spdlog/sinks/sink.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace spdlog { 18 | namespace sinks { 19 | /* 20 | * Windows color console sink. Uses WriteConsoleA to write to the console with 21 | * colors 22 | */ 23 | template 24 | class wincolor_sink : public sink 25 | { 26 | public: 27 | const WORD BOLD = FOREGROUND_INTENSITY; 28 | const WORD RED = FOREGROUND_RED; 29 | const WORD GREEN = FOREGROUND_GREEN; 30 | const WORD CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE; 31 | const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; 32 | const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN; 33 | 34 | wincolor_sink(HANDLE out_handle, color_mode mode); 35 | ~wincolor_sink() override; 36 | 37 | wincolor_sink(const wincolor_sink &other) = delete; 38 | wincolor_sink &operator=(const wincolor_sink &other) = delete; 39 | 40 | // change the color for the given level 41 | void set_color(level::level_enum level, WORD color); 42 | void log(const details::log_msg &msg) final override; 43 | void flush() final override; 44 | void set_pattern(const std::string &pattern) override final; 45 | void set_formatter(std::unique_ptr sink_formatter) override final; 46 | void set_color_mode(color_mode mode); 47 | 48 | protected: 49 | using mutex_t = typename ConsoleMutex::mutex_t; 50 | HANDLE out_handle_; 51 | mutex_t &mutex_; 52 | bool in_console_; 53 | bool should_do_colors_; 54 | std::unique_ptr formatter_; 55 | std::unordered_map colors_; 56 | 57 | // set foreground color and return the orig console attributes (for resetting later) 58 | WORD set_foreground_color_(WORD attribs); 59 | 60 | // print a range of formatted message to console 61 | void print_range_(const memory_buf_t &formatted, size_t start, size_t end); 62 | 63 | // in case we are redirected to file (not in console mode) 64 | void write_to_file_(const memory_buf_t &formatted); 65 | }; 66 | 67 | template 68 | class wincolor_stdout_sink : public wincolor_sink 69 | { 70 | public: 71 | explicit wincolor_stdout_sink(color_mode mode = color_mode::automatic); 72 | }; 73 | 74 | template 75 | class wincolor_stderr_sink : public wincolor_sink 76 | { 77 | public: 78 | explicit wincolor_stderr_sink(color_mode mode = color_mode::automatic); 79 | }; 80 | 81 | using wincolor_stdout_sink_mt = wincolor_stdout_sink; 82 | using wincolor_stdout_sink_st = wincolor_stdout_sink; 83 | 84 | using wincolor_stderr_sink_mt = wincolor_stderr_sink; 85 | using wincolor_stderr_sink_st = wincolor_stderr_sink; 86 | 87 | } // namespace sinks 88 | } // namespace spdlog 89 | 90 | #ifdef SPDLOG_HEADER_ONLY 91 | #include "wincolor_sink-inl.h" 92 | #endif 93 | -------------------------------------------------------------------------------- /includes/spdlog/spdlog-inl.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #ifndef SPDLOG_HEADER_ONLY 7 | #include "spdlog/spdlog.h" 8 | #endif 9 | 10 | #include "spdlog/common.h" 11 | #include "spdlog/details/pattern_formatter.h" 12 | 13 | namespace spdlog { 14 | 15 | SPDLOG_INLINE void initialize_logger(std::shared_ptr logger) 16 | { 17 | details::registry::instance().initialize_logger(std::move(logger)); 18 | } 19 | 20 | SPDLOG_INLINE std::shared_ptr get(const std::string &name) 21 | { 22 | return details::registry::instance().get(name); 23 | } 24 | 25 | SPDLOG_INLINE void set_formatter(std::unique_ptr formatter) 26 | { 27 | details::registry::instance().set_formatter(std::move(formatter)); 28 | } 29 | 30 | SPDLOG_INLINE void set_pattern(std::string pattern, pattern_time_type time_type) 31 | { 32 | set_formatter(std::unique_ptr(new pattern_formatter(std::move(pattern), time_type))); 33 | } 34 | 35 | SPDLOG_INLINE void enable_backtrace(size_t n_messages) 36 | { 37 | details::registry::instance().enable_backtrace(n_messages); 38 | } 39 | 40 | SPDLOG_INLINE void disable_backtrace() 41 | { 42 | details::registry::instance().disable_backtrace(); 43 | } 44 | 45 | SPDLOG_INLINE void dump_backtrace() 46 | { 47 | default_logger_raw()->dump_backtrace(); 48 | } 49 | 50 | SPDLOG_INLINE void set_level(level::level_enum log_level) 51 | { 52 | details::registry::instance().set_level(log_level); 53 | } 54 | 55 | SPDLOG_INLINE void flush_on(level::level_enum log_level) 56 | { 57 | details::registry::instance().flush_on(log_level); 58 | } 59 | 60 | SPDLOG_INLINE void flush_every(std::chrono::seconds interval) 61 | { 62 | details::registry::instance().flush_every(interval); 63 | } 64 | 65 | SPDLOG_INLINE void set_error_handler(void (*handler)(const std::string &msg)) 66 | { 67 | details::registry::instance().set_error_handler(handler); 68 | } 69 | 70 | SPDLOG_INLINE void register_logger(std::shared_ptr logger) 71 | { 72 | details::registry::instance().register_logger(std::move(logger)); 73 | } 74 | 75 | SPDLOG_INLINE void apply_all(const std::function)> &fun) 76 | { 77 | details::registry::instance().apply_all(fun); 78 | } 79 | 80 | SPDLOG_INLINE void drop(const std::string &name) 81 | { 82 | details::registry::instance().drop(name); 83 | } 84 | 85 | SPDLOG_INLINE void drop_all() 86 | { 87 | details::registry::instance().drop_all(); 88 | } 89 | 90 | SPDLOG_INLINE void shutdown() 91 | { 92 | details::registry::instance().shutdown(); 93 | } 94 | 95 | SPDLOG_INLINE void set_automatic_registration(bool automatic_registation) 96 | { 97 | details::registry::instance().set_automatic_registration(automatic_registation); 98 | } 99 | 100 | SPDLOG_INLINE std::shared_ptr default_logger() 101 | { 102 | return details::registry::instance().default_logger(); 103 | } 104 | 105 | SPDLOG_INLINE spdlog::logger *default_logger_raw() 106 | { 107 | return details::registry::instance().get_default_raw(); 108 | } 109 | 110 | SPDLOG_INLINE void set_default_logger(std::shared_ptr default_logger) 111 | { 112 | details::registry::instance().set_default_logger(std::move(default_logger)); 113 | } 114 | 115 | } // namespace spdlog -------------------------------------------------------------------------------- /includes/spdlog/tweakme.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | /////////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Edit this file to squeeze more performance, and to customize supported 9 | // features 10 | // 11 | /////////////////////////////////////////////////////////////////////////////// 12 | 13 | /////////////////////////////////////////////////////////////////////////////// 14 | // Under Linux, the much faster CLOCK_REALTIME_COARSE clock can be used. 15 | // This clock is less accurate - can be off by dozens of millis - depending on 16 | // the kernel HZ. 17 | // Uncomment to use it instead of the regular clock. 18 | // 19 | // #define SPDLOG_CLOCK_COARSE 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | /////////////////////////////////////////////////////////////////////////////// 23 | // Uncomment if date/time logging is not needed and never appear in the log 24 | // pattern. 25 | // This will prevent spdlog from querying the clock on each log call. 26 | // 27 | // WARNING: If the log pattern contains any date/time while this flag is on, the 28 | // result is undefined. 29 | // You must set new pattern(spdlog::set_pattern(..") without any 30 | // date/time in it 31 | // 32 | // #define SPDLOG_NO_DATETIME 33 | /////////////////////////////////////////////////////////////////////////////// 34 | 35 | /////////////////////////////////////////////////////////////////////////////// 36 | // Uncomment if thread id logging is not needed (i.e. no %t in the log pattern). 37 | // This will prevent spdlog from querying the thread id on each log call. 38 | // 39 | // WARNING: If the log pattern contains thread id (i.e, %t) while this flag is 40 | // on, the result is undefined. 41 | // 42 | // #define SPDLOG_NO_THREAD_ID 43 | /////////////////////////////////////////////////////////////////////////////// 44 | 45 | /////////////////////////////////////////////////////////////////////////////// 46 | // Uncomment to prevent spdlog from using thread local storage. 47 | // 48 | // WARNING: if your program forks, UNCOMMENT this flag to prevent undefined 49 | // thread ids in the children logs. 50 | // 51 | // #define SPDLOG_NO_TLS 52 | /////////////////////////////////////////////////////////////////////////////// 53 | 54 | /////////////////////////////////////////////////////////////////////////////// 55 | // Uncomment if logger name logging is not needed. 56 | // This will prevent spdlog from copying the logger name on each log call. 57 | // 58 | // #define SPDLOG_NO_NAME 59 | /////////////////////////////////////////////////////////////////////////////// 60 | 61 | /////////////////////////////////////////////////////////////////////////////// 62 | // Uncomment to avoid spdlog's usage of atomic log levels 63 | // Use only if your code never modifies a logger's log levels concurrently by 64 | // different threads. 65 | // 66 | // #define SPDLOG_NO_ATOMIC_LEVELS 67 | /////////////////////////////////////////////////////////////////////////////// 68 | 69 | /////////////////////////////////////////////////////////////////////////////// 70 | // Uncomment to enable usage of wchar_t for file names on Windows. 71 | // 72 | // #define SPDLOG_WCHAR_FILENAMES 73 | /////////////////////////////////////////////////////////////////////////////// 74 | 75 | /////////////////////////////////////////////////////////////////////////////// 76 | // Uncomment to override default eol ("\n" or "\r\n" under Linux/Windows) 77 | // 78 | // #define SPDLOG_EOL ";-)\n" 79 | /////////////////////////////////////////////////////////////////////////////// 80 | 81 | /////////////////////////////////////////////////////////////////////////////// 82 | // Uncomment to use your own copy of the fmt library instead of spdlog's copy. 83 | // In this case spdlog will try to include so set your -I flag 84 | // accordingly. 85 | // 86 | // #define SPDLOG_FMT_EXTERNAL 87 | /////////////////////////////////////////////////////////////////////////////// 88 | 89 | /////////////////////////////////////////////////////////////////////////////// 90 | // Uncomment to enable wchar_t support (convert to utf8) 91 | // 92 | // #define SPDLOG_WCHAR_TO_UTF8_SUPPORT 93 | /////////////////////////////////////////////////////////////////////////////// 94 | 95 | /////////////////////////////////////////////////////////////////////////////// 96 | // Uncomment to prevent child processes from inheriting log file descriptors 97 | // 98 | // #define SPDLOG_PREVENT_CHILD_FD 99 | /////////////////////////////////////////////////////////////////////////////// 100 | 101 | /////////////////////////////////////////////////////////////////////////////// 102 | // Uncomment to customize level names (e.g. "MT TRACE") 103 | // 104 | // #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", 105 | // "MY ERROR", "MY CRITICAL", "OFF" } 106 | /////////////////////////////////////////////////////////////////////////////// 107 | 108 | /////////////////////////////////////////////////////////////////////////////// 109 | // Uncomment to customize short level names (e.g. "MT") 110 | // These can be longer than one character. 111 | // 112 | // #define SPDLOG_SHORT_LEVEL_NAMES { "T", "D", "I", "W", "E", "C", "O" } 113 | /////////////////////////////////////////////////////////////////////////////// 114 | 115 | /////////////////////////////////////////////////////////////////////////////// 116 | // Uncomment to disable default logger creation. 117 | // This might save some (very) small initialization time if no default logger is needed. 118 | // 119 | // #define SPDLOG_DISABLE_DEFAULT_LOGGER 120 | /////////////////////////////////////////////////////////////////////////////// 121 | 122 | /////////////////////////////////////////////////////////////////////////////// 123 | // Uncomment and set to compile time level with zero cost (default is INFO). 124 | // Macros like SPDLOG_DEBUG(..), SPDLOG_INFO(..) will expand to empty statements if not enabled 125 | // 126 | // #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO 127 | /////////////////////////////////////////////////////////////////////////////// 128 | 129 | /////////////////////////////////////////////////////////////////////////////// 130 | // Uncomment (and change if desired) macro to use for function names. 131 | // This is compiler dependent. 132 | // __PRETTY_FUNCTION__ might be nicer in clang/gcc, and __FUNCTION__ in msvc. 133 | // Defaults to __FUNCTION__ (should work on all compilers) if not defined. 134 | // 135 | // #define SPDLOG_FUNCTION __PRETTY_FUNCTION__ 136 | /////////////////////////////////////////////////////////////////////////////// 137 | -------------------------------------------------------------------------------- /includes/spdlog/version.h: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #pragma once 5 | 6 | #define SPDLOG_VER_MAJOR 1 7 | #define SPDLOG_VER_MINOR 4 8 | #define SPDLOG_VER_PATCH 0 9 | 10 | #define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH) 11 | -------------------------------------------------------------------------------- /input_files/appendfile.txt: -------------------------------------------------------------------------------- 1 | dev 2 | test 3 | -------------------------------------------------------------------------------- /input_files/excludefile.txt: -------------------------------------------------------------------------------- 1 | test.example.com -------------------------------------------------------------------------------- /input_files/extension_file.txt: -------------------------------------------------------------------------------- 1 | .com.au 2 | .co.uk -------------------------------------------------------------------------------- /input_files/set_list.txt: -------------------------------------------------------------------------------- 1 | one 2 | two 3 | three -------------------------------------------------------------------------------- /input_files/target_list.txt: -------------------------------------------------------------------------------- 1 | example.com 2 | help.example.com 3 | test.example.com 4 | one.example.com 5 | 101.example.com -------------------------------------------------------------------------------- /main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingo/DNSCewl/42bcd521af3285a1cca32753104ee213d18dc9cb/main.o -------------------------------------------------------------------------------- /sets/aws-zones.txt: -------------------------------------------------------------------------------- 1 | ap-northeast-1 2 | ap-northeast-2 3 | ap-northeast-3 4 | ap-south-1 5 | ap-southeast-1 6 | ap-southeast-2 7 | ca-central-1 8 | eu-central-1 9 | eu-north-1 10 | eu-west-1 11 | eu-west-2 12 | eu-west-3 13 | sa-east-1 14 | us-east-1 15 | us-east-2 16 | us-west-1 17 | us-west-2 18 | ap-east-1 19 | -------------------------------------------------------------------------------- /sets/non-production-hosts.txt: -------------------------------------------------------------------------------- 1 | qa 2 | devenv 3 | devenv1 4 | devenv2 5 | devenv3 6 | preprod 7 | pre-prod 8 | test 9 | testing 10 | staging 11 | stage 12 | dev 13 | development 14 | deploy 15 | slave 16 | master 17 | review 18 | prod 19 | uat 20 | prep 21 | version2 22 | 23 | --------------------------------------------------------------------------------