1 //
2 // Copyright(c) 2015 Gabi Melman.
3 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
4 //
5 
6 /* -*- MODE: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
7 /*
8  *     Copyright 2017 Couchbase, Inc
9  *
10  *   Licensed under the Apache License, Version 2.0 (the "License");
11  *   you may not use this file except in compliance with the License.
12  *   You may obtain a copy of the License at
13  *
14  *       http://www.apache.org/licenses/LICENSE-2.0
15  *
16  *   Unless required by applicable law or agreed to in writing, software
17  *   distributed under the License is distributed on an "AS IS" BASIS,
18  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  *   See the License for the specific language governing permissions and
20  *   limitations under the License.
21  */
22 
23 #pragma once
24 
25 #include <spdlog/sinks/base_sink.h>
26 
27 namespace spdlog {
28 namespace details {
29 class file_helper;
30 } // namespace details
31 } // namespace spdlog
32 
33 /**
34  * Customised version of spdlog's rotating_file_sink with the following
35  * modifications:
36  *
37  * 1 Adds open and closing tags in the file so that a concatenated version
38  *   of all of the log files may be split back into its fragments again
39  *
40  * 2 Instead of renaming all of the files every time we're rotating to
41  *   the next file we start a new log file with a higher number
42  *
43  * TODO: If updating spdlog from v1.1.0, check if this class also needs
44  *       updating.
45  */
46 template <class Mutex>
47 class custom_rotating_file_sink : public spdlog::sinks::base_sink<Mutex> {
48 public:
49     custom_rotating_file_sink(const spdlog::filename_t& base_filename,
50                               std::size_t max_size,
51                               const std::string& log_pattern);
52 
53     ~custom_rotating_file_sink() override;
54 
55 protected:
56     void sink_it_(const spdlog::details::log_msg& msg) override;
57     void flush_() override;
58 
59 private:
60     void addHook(const std::string& hook);
61     // Calculate the full filename to use the next time
62     spdlog::filename_t calc_filename();
63 
64     const spdlog::filename_t _base_filename;
65     const std::size_t _max_size;
66     std::size_t _current_size;
67     std::unique_ptr<spdlog::details::file_helper> _file_helper;
68     std::unique_ptr<spdlog::pattern_formatter> formatter;
69     unsigned long _next_file_id;
70 
71     const std::string openingLogfile{"---------- Opening logfile: "};
72     const std::string closingLogfile{"---------- Closing logfile"};
73 };
74 
75 using custom_rotating_file_sink_mt = custom_rotating_file_sink<std::mutex>;
76 using custom_rotating_file_sink_st =
77         custom_rotating_file_sink<spdlog::details::null_mutex>;
78