third_party.pigweed.src/pw_log_basic/log_basic.cc
Rob Mohr f1bf169cd2 *: Use new TODO style
Change-Id: I94819991c2831363bd3a044197a98db86f345b10
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/170730
Pigweed-Auto-Submit: Rob Mohr <mohrr@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Chinchilla <cachinchilla@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
2023-09-18 18:39:27 +00:00

163 lines
4.6 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
// This is a very basic direct output log implementation with no buffering.
#include "pw_log_basic/log_basic.h"
#include <cstring>
#include "pw_log/levels.h"
#include "pw_log_basic_private/config.h"
#include "pw_string/string_builder.h"
#include "pw_sys_io/sys_io.h"
// ANSI color constants to control the terminal. Not Windows compatible.
// clang-format off
#define MAGENTA "\033[35m"
#define YELLOW "\033[33m"
#define RED "\033[31m"
#define GREEN "\033[32m"
#define BLUE "\033[96m"
#define BLACK "\033[30m"
#define YELLOW_BG "\033[43m"
#define WHITE_BG "\033[47m"
#define RED_BG "\033[41m"
#define BOLD "\033[1m"
#define RESET "\033[0m"
// clang-format on
namespace pw::log_basic {
namespace {
const char* LogLevelToLogLevelName(int level) {
switch (level) {
// clang-format off
#if PW_EMOJI
case PW_LOG_LEVEL_DEBUG : return "👾" RESET;
case PW_LOG_LEVEL_INFO : return " " RESET;
case PW_LOG_LEVEL_WARN : return "⚠️ " RESET;
case PW_LOG_LEVEL_ERROR : return "" RESET;
case PW_LOG_LEVEL_CRITICAL : return "☠️ " RESET;
default: return "" RESET;
#else
case PW_LOG_LEVEL_DEBUG : return BLUE BOLD "DBG" RESET;
case PW_LOG_LEVEL_INFO : return MAGENTA BOLD "INF" RESET;
case PW_LOG_LEVEL_WARN : return YELLOW BOLD "WRN" RESET;
case PW_LOG_LEVEL_ERROR : return RED BOLD "ERR" RESET;
case PW_LOG_LEVEL_CRITICAL : return BLACK BOLD RED_BG "FTL" RESET;
default : return GREEN BOLD "UNK" RESET;
#endif
// clang-format on
}
}
#if PW_LOG_SHOW_FILENAME
const char* GetFileBasename(const char* filename) {
int length = std::strlen(filename);
if (length == 0) {
return filename;
}
// Start on the last character.
// TODO(pwbug/38): This part of the function doesn't work for Windows paths.
const char* basename = filename + std::strlen(filename) - 1;
while (basename != filename && *basename != '/') {
basename--;
}
if (*basename == '/') {
basename++;
}
return basename;
}
#endif // PW_LOG_SHOW_FILENAME
void (*write_log)(std::string_view) = [](std::string_view log) {
sys_io::WriteLine(log)
.IgnoreError(); // TODO: b/242598609 - Handle Status properly
};
} // namespace
// This is a fully loaded, inefficient-at-the-callsite, log implementation.
extern "C" void pw_Log(int level,
unsigned int flags,
const char* module_name,
const char* file_name,
int line_number,
const char* function_name,
const char* message,
...) {
// Accumulate the log message in this buffer, then output it.
pw::StringBuffer<PW_LOG_BASIC_ENTRY_SIZE> buffer;
// Column: Timestamp
// Note that this macro method defaults to a no-op.
PW_LOG_APPEND_TIMESTAMP(buffer);
// Column: Filename
#if PW_LOG_SHOW_FILENAME
buffer.Format(" %-30s:%4d |", GetFileBasename(file_name), line_number);
#else
static_cast<void>(file_name);
static_cast<void>(line_number);
#endif
// Column: Function
#if PW_LOG_SHOW_FUNCTION
buffer.Format(" %20s |", function_name);
#else
static_cast<void>(function_name);
#endif
// Column: Module
#if PW_LOG_SHOW_MODULE
buffer << " " BOLD;
buffer.Format("%3s", module_name);
buffer << RESET " ";
#else
static_cast<void>(module_name);
#endif // PW_LOG_SHOW_MODULE
// Column: Flag
#if PW_LOG_SHOW_FLAG
#if PW_EMOJI
buffer << (flags ? "🚩" : " ");
#else
buffer << (flags ? "*" : "|");
#endif // PW_EMOJI
buffer << " ";
#else
static_cast<void>(flags);
#endif // PW_LOG_SHOW_FLAG
// Column: Level
buffer << LogLevelToLogLevelName(level) << " ";
// Column: Message
va_list args;
va_start(args, message);
buffer.FormatVaList(message, args);
va_end(args);
// All done; flush the log.
write_log(buffer);
}
void SetOutput(void (*log_output)(std::string_view log)) {
write_log = log_output;
}
} // namespace pw::log_basic