logger.hpp
1 /*
2  * Copyright (c) 2020-2021, 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 // If using GCC, temporary workaround for older libcudacxx defining _LIBCPP_VERSION
20 // undefine it before including spdlog, due to fmtlib checking if it is defined
21 // TODO: remove once libcudacxx is on Github and RAPIDS depends on it
22 #ifdef __GNUG__
23 #undef _LIBCPP_VERSION
24 #endif
25 #include <spdlog/sinks/basic_file_sink.h>
26 #include <spdlog/spdlog.h>
27 
28 #include <iostream>
29 #include <string>
30 
31 namespace rmm {
32 
33 namespace detail {
34 
43 inline std::string default_log_filename()
44 {
45  auto* filename = std::getenv("RMM_DEBUG_LOG_FILE");
46  return (filename == nullptr) ? std::string{"rmm_log.txt"} : std::string{filename};
47 }
48 
49 // Simple wrapper around a spdlog::logger that performs RMM-specific initialization
51  spdlog::logger logger_;
52 
54  : logger_{"RMM",
55  std::make_shared<spdlog::sinks::basic_file_sink_mt>(
56  default_log_filename(), true // truncate file
57  )}
58  {
59  logger_.set_pattern("[%6t][%H:%M:%S:%f][%-6l] %v");
60  logger_.flush_on(spdlog::level::warn);
61 #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO
62 #ifdef CUDA_API_PER_THREAD_DEFAULT_STREAM
63  logger_.info("----- RMM LOG BEGIN [PTDS ENABLED] -----");
64 #else
65  logger_.info("----- RMM LOG BEGIN [PTDS DISABLED] -----");
66 #endif
67  logger_.flush();
68 #endif
69  }
70 };
71 
75 struct bytes {
76  std::size_t value;
77 
78  friend std::ostream& operator<<(std::ostream& os, bytes const& value)
79  {
80  static std::array units{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"};
81 
82  int index = 0;
83  auto size = static_cast<double>(value.value);
84  while (size > 1024) {
85  size /= 1024;
86  index++;
87  }
88  return os << size << ' ' << units.at(index);
89  }
90 };
91 
92 } // namespace detail
93 
101 inline spdlog::logger& logger()
102 {
103  static detail::logger_wrapper wrapped{};
104  return wrapped.logger_;
105 }
106 
107 // The default is INFO, but it should be used sparingly, so that by default a log file is only
108 // output if there is important information, warnings, errors, and critical failures
109 // Log messages that require computation should only be used at level TRACE and DEBUG
110 #define RMM_LOG_TRACE(...) SPDLOG_LOGGER_TRACE(&rmm::logger(), __VA_ARGS__)
111 #define RMM_LOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(&rmm::logger(), __VA_ARGS__)
112 #define RMM_LOG_INFO(...) SPDLOG_LOGGER_INFO(&rmm::logger(), __VA_ARGS__)
113 #define RMM_LOG_WARN(...) SPDLOG_LOGGER_WARN(&rmm::logger(), __VA_ARGS__)
114 #define RMM_LOG_ERROR(...) SPDLOG_LOGGER_ERROR(&rmm::logger(), __VA_ARGS__)
115 #define RMM_LOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(&rmm::logger(), __VA_ARGS__)
116 
117 } // namespace rmm
rmm::detail::bytes
Represent a size in number of bytes.
Definition: logger.hpp:75
rmm::detail::logger_wrapper
Definition: logger.hpp:50