Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit

Permalink
vm_tools: sommelier: Add Chromium-like logging macros and functions
Browse files Browse the repository at this point in the history
This adds simple functions to print messages in various levels.
To print the messages, Sommelier needs to be built with
-Dlog_level=X with some number.

Example usage:

```
LOG(INFO) << window << " says hello world";
LOG(INFO) << "hello world";
```

BUG=b:328699937,b:331688838
TEST=N/A

Change-Id: Ie06fb1678b27320648cfd300beefdcaddb35441e
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/5464981
Reviewed-by: Chloe Pelling <[email protected]>
Tested-by: Max Lee <[email protected]>
Commit-Queue: Max Lee <[email protected]>
  • Loading branch information
Max Lee authored and Chromeos LUCI committed Apr 23, 2024
1 parent b0dd93e commit a2eba69
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 0 deletions.
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static_library("libsommelier") {
"sommelier-gtk-shell.cc",
"sommelier-idle-inhibit-manager.cc",
"sommelier-inpututils.cc",
"sommelier-logging.cc",
"sommelier-output.cc",
"sommelier-pointer-constraints.cc",
"sommelier-relative-pointer-manager.cc",
Expand Down
7 changes: 7 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ if get_option('quirks')
cpp_args += '-DQUIRKS_SUPPORT'
endif

#===========#
# Log level #
#===========#

cpp_args += '-DLOG_LEVEL=' + get_option('log_level').to_string()

#===========#
# Sommelier #
#===========#
Expand Down Expand Up @@ -205,6 +211,7 @@ libsommelier = static_library(
'sommelier-global.cc',
'sommelier-idle-inhibit-manager.cc',
'sommelier-inpututils.cc',
'sommelier-logging.cc',
'sommelier-output.cc',
'sommelier-pointer-constraints.cc',
'sommelier-relative-pointer-manager.cc',
Expand Down
6 changes: 6 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,9 @@ option('with_tests',
value: true,
description: 'build the sommelier_test target'
)

option('log_level',
type: 'integer',
value: 0,
description: 'log level to print, -1 prints everything, default is 0 (up to INFO)'
)
33 changes: 33 additions & 0 deletions sommelier-logging.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sommelier-logging.h" // NOLINT(build/include_directory)

namespace logging {

std::string file_name(std::string file_path) {
// Extract file name from file path.
auto found = file_path.find_last_of('/');
if (found != std::string::npos) {
return file_path.substr(found + 1);
}
return file_path;
}

std::string log_level_to_string(int level) {
if (level == LOG_LEVEL_VERBOSE) {
return "VERBOSE";
} else if (level == LOG_LEVEL_INFO) {
return "INFO";
} else if (level == LOG_LEVEL_WARNING) {
return "WARNING";
} else if (level == LOG_LEVEL_ERROR) {
return "ERROR";
} else if (level == LOG_LEVEL_FATAL) {
return "FATAL";
}
return std::to_string(level);
}

} // namespace logging
95 changes: 95 additions & 0 deletions sommelier-logging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Very simple logger that is similar to Chromium's logger. Example usage:
// LOG(INFO) << "hello world";
// LOG(INFO) << window << " says hello world";

#ifndef VM_TOOLS_SOMMELIER_SOMMELIER_LOGGING_H_
#define VM_TOOLS_SOMMELIER_SOMMELIER_LOGGING_H_

#include <cstdarg>
#include <cstring>
#include <iosfwd>
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>

#include "sommelier-window.h" // NOLINT(build/include_directory)

// Build Sommelier with -Dlog_level=X to define LOG_LEVEL
#ifndef LOG_LEVEL
// Default log level is INFO
#define LOG_LEVEL 0
#endif // LOG_LEVEL

// Predefined log levels
constexpr int LOG_LEVEL_VERBOSE = -1;
constexpr int LOG_LEVEL_INFO = 0;
constexpr int LOG_LEVEL_WARNING = 1;
constexpr int LOG_LEVEL_ERROR = 2;
constexpr int LOG_LEVEL_FATAL = 3;

#define LOG(level) \
::logging::Log(LOG_LEVEL_##level, __func__, ::logging::file_name(__FILE__), \
__LINE__)

namespace logging {

std::string file_name(std::string file_path);
std::string log_level_to_string(int level);

class Log {
private:
std::stringstream log_content;

public:
std::string function;
std::string file;
int line;
int log_level;

explicit Log(int log_level,
std::string function,
std::string file,
int line) {
this->log_level = log_level;
this->function = function;
this->file = file;
this->line = line;
}

template <typename T>
Log& operator<<(T const& value) {
if (log_level >= LOG_LEVEL) {
this->log_content << value;
}
return *this;
}

Log& operator<<(sl_window* window) {
*this << "(" << window->name << "#" << std::hex << window->id << ")"
<< std::dec;
return *this;
}

~Log() {
// Example expected usage:
// LOG(INFO) << "hello world ";
// Temporary objects are destroyed after the end of the expression, which
// means this destructor is called at 'semicolon', resulting in printing to
// cerr.
if (this->log_content.peek() == EOF) {
return;
}
std::cerr << log_level_to_string(this->log_level) << " <" << this->file
<< ":" << this->line << "> " << this->function << ": "
<< this->log_content.rdbuf() << std::endl;
}
};

} // namespace logging

#endif // VM_TOOLS_SOMMELIER_SOMMELIER_LOGGING_H_

0 comments on commit a2eba69

Please sign in to comment.