File: Logger.cpp

package info (click to toggle)
vecgeom 1.2.8%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 24,016 kB
  • sloc: cpp: 88,803; ansic: 6,888; python: 1,035; sh: 582; sql: 538; makefile: 23
file content (131 lines) | stat: -rw-r--r-- 4,355 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//----------------------------------*-C++-*----------------------------------//
// Copyright 2020-2023 UT-Battelle, LLC, and other Celeritas developers.
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file Logger.cpp
//---------------------------------------------------------------------------//
#include "VecGeom/management/Logger.h"

#include <algorithm>
#include <functional>
#include <iostream>
#include <cassert>
#include <mutex>
#include <sstream>
#include <string>

#include "VecGeom/management/LoggerTypes.h"
#include "VecGeom/management/Environment.h"
#include "VecGeom/management/ColorUtils.h"

namespace vecgeom {

namespace {
//---------------------------------------------------------------------------//
// HELPER CLASSES
//---------------------------------------------------------------------------//
//! Default global logger prints the error message with basic colors
void default_global_handler(Provenance prov, LogLevel lev, std::string msg)
{
  static std::mutex log_mutex;
  std::lock_guard<std::mutex> scoped_lock{log_mutex};

  if (lev == LogLevel::debug || lev >= LogLevel::warning) {
    // Output problem line/file for debugging or high level
    std::clog << color_code('x') << prov.file;
    if (prov.line) std::clog << ':' << prov.line;
    std::clog << color_code(' ') << ": ";
  }

  // clang-format off
    char c = ' ';
    switch (lev)
    {
        case LogLevel::debug:      c = 'x'; break;
        case LogLevel::diagnostic: c = 'x'; break;
        case LogLevel::status:     c = 'b'; break;
        case LogLevel::info:       c = 'g'; break;
        case LogLevel::warning:    c = 'y'; break;
        case LogLevel::error:      c = 'r'; break;
        case LogLevel::critical:   c = 'R'; break;
        case LogLevel::size_: assert(false);
    };
  // clang-format on
  std::clog << color_code(c) << to_cstring(lev) << ": " << color_code(' ') << msg << std::endl;
}

//---------------------------------------------------------------------------//
/*!
 * Set the log level from an environment variable, warn on failure.
 */
void set_log_level_from_env(Logger *log, std::string const &level_env)
{
  assert(log);
  try {
    log->level(log_level_from_env(level_env));
  } catch (std::runtime_error const &e) {
    (*log)(VECGEOM_CODE_PROVENANCE, LogLevel::warning) << e.what();
  }
}

//---------------------------------------------------------------------------//
} // namespace

//---------------------------------------------------------------------------//
/*!
 * Construct with log handler.
 */
Logger::Logger(LogHandler handle) : handle_{std::move(handle)} {}

//---------------------------------------------------------------------------//
// FREE FUNCTIONS
//---------------------------------------------------------------------------//
/*!
 * Get the log level from an environment variable.
 */
LogLevel log_level_from_env(std::string const &level_env)
{
  // Search for the provided environment variable to set the default
  // logging level using the `to_cstring` function in LoggerTypes.
  std::string const &env_value = vecgeom::getenv(level_env);
  if (env_value.empty()) {
    return Logger::default_level();
  }

  for (int i = 0; i < static_cast<int>(LogLevel::size_); ++i) {
    if (env_value == to_cstring(static_cast<LogLevel>(i))) {
      return static_cast<LogLevel>(i);
    }
  }
  throw std::runtime_error("invalid log level in environment variable");
}

//---------------------------------------------------------------------------//
/*!
 * Create a default logger using the world communicator.
 *
 * This function can be useful when resetting a test harness.
 */
Logger make_default_logger()
{
  Logger log{&default_global_handler};
  set_log_level_from_env(&log, "VECGEOM_LOG");
  return log;
}

//---------------------------------------------------------------------------//
/*!
 * Parallel-enabled logger: print only on "main" process.
 *
 * Setting the "VECGEOM_LOG" environment variable to "debug", "info", "error",
 * etc. will change the default log level.
 */
Logger &logger()
{
  static Logger logger = make_default_logger();
  return logger;
}

//---------------------------------------------------------------------------//
} // namespace vecgeom