Hazelcast C++ Client
Hazelcast C++ Client Library
logger.cpp
1 /*
2 * Copyright (c) 2008-2022, Hazelcast, Inc. 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 
17 #include <iomanip>
18 #include <iostream>
19 #include <sstream>
20 #include <chrono>
21 #include <ctime>
22 #include <thread>
23 
24 #include "hazelcast/logger.h"
25 #include "hazelcast/client/hazelcast_client.h"
26 
27 namespace hazelcast {
28 
29 std::ostream& operator<<(std::ostream &os, logger::level lvl) {
30  switch (lvl) {
31  case logger::level::severe:
32  os << "SEVERE";
33  break;
34  case logger::level::warning:
35  os << "WARNING";
36  break;
37  case logger::level::info:
38  os << "INFO";
39  break;
40  case logger::level::fine:
41  os << "FINE";
42  break;
43  case logger::level::finer:
44  os << "FINER";
45  break;
46  case logger::level::finest:
47  os << "FINEST";
48  break;
49  default:
50  os << static_cast<int>(lvl);
51  break;
52  }
53  return os;
54 }
55 
56 logger::logger(std::string instance_name, std::string cluster_name, level level, handler_type handler)
57  : instance_name_{ std::move(instance_name) }
58  , cluster_name_{ std::move(cluster_name) }
59  , level_{ level }
60  , handler_{ std::move(handler) }
61 {}
62 
63 bool logger::enabled(level lvl) noexcept {
64  return lvl >= level_;
65 }
66 
67 void logger::log(level lvl, const std::string &msg) noexcept {
68  handler_(instance_name_, cluster_name_, lvl, msg);
69 }
70 
71 namespace {
72 
73 std::tm time_t_to_localtime(const std::time_t &t) {
74  std::tm lt;
75 
76 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
77  ::localtime_s(&lt, &t);
78 #else
79  ::localtime_r(&t, &lt);
80 #endif
81 
82  return lt;
83 }
84 
85 }
86 
87 std::mutex logger::cout_lock_;
88 
89 void
90 logger::default_handler(const std::string& instance_name,
91  const std::string& cluster_name,
92  level lvl,
93  const std::string& msg) noexcept
94 {
95 
96  auto tp = std::chrono::system_clock::now();
97  auto t = std::chrono::system_clock::to_time_t(tp);
98  auto local_t = time_t_to_localtime(t);
99 
100  auto dur = tp.time_since_epoch();
101  auto sec = std::chrono::duration_cast<std::chrono::seconds>(dur);
102 
103  auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(dur - sec).count();
104 
105  std::ostringstream sstrm;
106 
107  char time_buffer[80];
108  std::strftime(time_buffer, sizeof(time_buffer), "%d/%m/%Y %H:%M:%S.", &local_t);
109  sstrm << time_buffer
110  << std::setfill('0') << std::setw(3) << ms << ' '
111  << lvl << ": [" << std::this_thread::get_id() << "] "
112  << instance_name << '[' << cluster_name << "] ["
113  << client::version() << "] "
114  << msg
115  << '\n';
116 
117  {
118  std::lock_guard<std::mutex> g(cout_lock_);
119  std::cout << sstrm.str() << std::flush;
120  }
121 }
122 
123 
124 } // namespace hazelcast