86 lines · cpp
1//===--- Logger.cpp - Logger interface for clangd -------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "support/Logger.h"10#include "support/Trace.h"11#include "llvm/Support/Chrono.h"12#include "llvm/Support/Error.h"13#include "llvm/Support/FormatVariadic.h"14#include "llvm/Support/raw_ostream.h"15#include <mutex>16 17namespace clang {18namespace clangd {19 20namespace {21Logger *L = nullptr;22} // namespace23 24LoggingSession::LoggingSession(clangd::Logger &Instance) {25 assert(!L);26 L = &Instance;27}28 29LoggingSession::~LoggingSession() { L = nullptr; }30 31void detail::logImpl(Logger::Level Level, const char *Fmt,32 const llvm::formatv_object_base &Message) {33 if (L)34 L->log(Level, Fmt, Message);35 else {36 static std::mutex Mu;37 std::lock_guard<std::mutex> Guard(Mu);38 llvm::errs() << Message << "\n";39 }40}41 42const char *detail::debugType(const char *Filename) {43 if (const char *Slash = strrchr(Filename, '/'))44 return Slash + 1;45 if (const char *Backslash = strrchr(Filename, '\\'))46 return Backslash + 1;47 return Filename;48}49 50void StreamLogger::log(Logger::Level Level, const char *Fmt,51 const llvm::formatv_object_base &Message) {52 if (Level < MinLevel)53 return;54 llvm::sys::TimePoint<> Timestamp = std::chrono::system_clock::now();55 trace::log(Message);56 std::lock_guard<std::mutex> Guard(StreamMutex);57 Logs << llvm::formatv("{0}[{1:%H:%M:%S.%L}] {2}\n", indicator(Level),58 Timestamp, Message);59 Logs.flush();60}61 62namespace {63// Like llvm::StringError but with fewer options and no gratuitous copies.64class SimpleStringError : public llvm::ErrorInfo<SimpleStringError> {65 std::error_code EC;66 std::string Message;67 68public:69 SimpleStringError(std::error_code EC, std::string &&Message)70 : EC(EC), Message(std::move(Message)) {}71 void log(llvm::raw_ostream &OS) const override { OS << Message; }72 std::string message() const override { return Message; }73 std::error_code convertToErrorCode() const override { return EC; }74 static char ID;75};76char SimpleStringError::ID;77 78} // namespace79 80llvm::Error detail::error(std::error_code EC, std::string &&Msg) {81 return llvm::make_error<SimpleStringError>(EC, std::move(Msg));82}83 84} // namespace clangd85} // namespace clang86