1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15
16 * \author Haichao.chc
17 * \date Oct 2020
18 * \brief Implementation of index logger, based on glog
19 */
20
21#include <ailego/io/file.h>
22#include <aitheta2/index_factory.h>
23
24#ifdef __GNUC__
25#pragma GCC diagnostic push
26#pragma GCC diagnostic ignored "-Wshadow"
27#pragma GCC diagnostic ignored "-Wunused-parameter"
28#endif
29
30#include <glog/logging.h>
31
32#ifdef __GNUC__
33#pragma GCC diagnostic pop
34#endif
35
36namespace google {
37namespace glog_internal_namespace_ {
38extern bool IsGoogleLoggingInitialized(void);
39extern bool ShutdownGoogleLoggingUtilities(void);
40} // namespace glog_internal_namespace_
41} // namespace google
42
43namespace proxima {
44namespace be {
45
46class AppendLogger : public aitheta2::IndexLogger {
47 public:
48 AppendLogger() = default;
49
50 ~AppendLogger() {
51 this->cleanup();
52 }
53
54 public:
55 int init(const aitheta2::IndexParams &params) override {
56 if (!google::glog_internal_namespace_::IsGoogleLoggingInitialized()) {
57 std::string log_dir = params.get_as_string("proxima.file.logger.log_dir");
58 std::string log_file =
59 params.get_as_string("proxima.file.logger.log_file");
60
61 if (!ailego::File::IsExist(log_dir)) {
62 ailego::File::MakePath(log_dir);
63 }
64
65 FLAGS_log_dir = log_dir;
66 FLAGS_max_log_size = 2048;
67 FLAGS_logbufsecs = 0;
68 // it's really a bad feature for glog
69 // logs <= LOG_FATAL will also output to stderr
70 // and we can only set FATAL at most
71 // and so we should avoid to use LOG_FATAL
72 FLAGS_stderrthreshold = google::GLOG_FATAL;
73
74 static std::string new_log_file = log_file;
75 google::InitGoogleLogging(new_log_file.c_str());
76 }
77 return 0;
78 }
79
80 int cleanup() override {
81 if (google::glog_internal_namespace_::IsGoogleLoggingInitialized()) {
82 google::ShutdownGoogleLogging();
83 }
84 return 0;
85 }
86
87 void log(int level, const char *file, int line, const char *format,
88 va_list args) override {
89 static google::LogSeverity severities[] = {
90 google::GLOG_INFO, google::GLOG_INFO, google::GLOG_WARNING,
91 google::GLOG_ERROR, google::GLOG_FATAL};
92 char buf[2048];
93 vsnprintf(buf, sizeof(buf), format, args);
94 google::LogMessage(file, line, severities[level]).stream() << buf;
95 google::FlushLogFiles(severities[level]);
96 }
97};
98
99INDEX_FACTORY_REGISTER_LOGGER(AppendLogger);
100
101} // namespace be
102} // end namespace proxima
103