logger.hpp
1 /*
2  * Copyright (c) 2020-2023, NVIDIA CORPORATION.
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 #pragma once
18 
19 #include <fmt/format.h>
20 #include <fmt/ostream.h>
21 #include <spdlog/sinks/basic_file_sink.h>
22 #include <spdlog/spdlog.h>
23 
24 #include <array>
25 #include <iostream>
26 #include <string>
27 
28 namespace rmm {
29 
30 namespace detail {
31 
40 inline std::string default_log_filename()
41 {
42  auto* filename = std::getenv("RMM_DEBUG_LOG_FILE");
43  return (filename == nullptr) ? std::string{"rmm_log.txt"} : std::string{filename};
44 }
45 
51 
53  : logger_{"RMM",
54  std::make_shared<spdlog::sinks::basic_file_sink_mt>(
55  default_log_filename(), true // truncate file
56  )}
57  {
58  logger_.set_pattern("[%6t][%H:%M:%S:%f][%-6l] %v");
59  logger_.flush_on(spdlog::level::warn);
60 #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO
61 #ifdef CUDA_API_PER_THREAD_DEFAULT_STREAM
62  logger_.info("----- RMM LOG BEGIN [PTDS ENABLED] -----");
63 #else
64  logger_.info("----- RMM LOG BEGIN [PTDS DISABLED] -----");
65 #endif
66  logger_.flush();
67 #endif
68  }
69 };
70 
74 struct bytes {
75  std::size_t value;
76 
83  friend std::ostream& operator<<(std::ostream& os, bytes const& value)
84  {
85  static std::array units{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"};
86 
87  int index = 0;
88  auto size = static_cast<double>(value.value);
89  while (size > 1024) {
90  size /= 1024;
91  index++;
92  }
93  return os << size << ' ' << units.at(index);
94  }
95 };
96 
97 } // namespace detail
98 
109 {
110  static detail::logger_wrapper wrapped{};
111  return wrapped.logger_;
112 }
113 
115 //
116 // The default is INFO, but it should be used sparingly, so that by default a log file is only
117 // output if there is important information, warnings, errors, and critical failures
118 // Log messages that require computation should only be used at level TRACE and DEBUG
119 #define RMM_LOG_TRACE(...) SPDLOG_LOGGER_TRACE(&rmm::logger(), __VA_ARGS__)
120 #define RMM_LOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(&rmm::logger(), __VA_ARGS__)
121 #define RMM_LOG_INFO(...) SPDLOG_LOGGER_INFO(&rmm::logger(), __VA_ARGS__)
122 #define RMM_LOG_WARN(...) SPDLOG_LOGGER_WARN(&rmm::logger(), __VA_ARGS__)
123 #define RMM_LOG_ERROR(...) SPDLOG_LOGGER_ERROR(&rmm::logger(), __VA_ARGS__)
124 #define RMM_LOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(&rmm::logger(), __VA_ARGS__)
125 
127 
128 } // namespace rmm
129 
130 // Doxygen doesn't like this because we're overloading something from fmt
132 template <>
133 struct fmt::formatter<rmm::detail::bytes> : fmt::ostream_formatter {};
134 
spdlog::logger & logger()
Returns the global RMM logger.
Definition: logger.hpp:108
Represent a size in number of bytes.
Definition: logger.hpp:74
friend std::ostream & operator<<(std::ostream &os, bytes const &value)
Construct a new bytes object.
Definition: logger.hpp:83
std::size_t value
The size in bytes.
Definition: logger.hpp:75
Simple wrapper around a spdlog::logger that performs RMM-specific initialization.
Definition: logger.hpp:49
spdlog::logger logger_
The underlying logger.
Definition: logger.hpp:50