1ad97ccf6SSam McCall //===--- Logger.cpp - Logger interface for clangd -------------------------===//
2ad97ccf6SSam McCall //
3ad97ccf6SSam McCall // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ad97ccf6SSam McCall // See https://llvm.org/LICENSE.txt for license information.
5ad97ccf6SSam McCall // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ad97ccf6SSam McCall //
7ad97ccf6SSam McCall //===----------------------------------------------------------------------===//
8ad97ccf6SSam McCall
9ad97ccf6SSam McCall #include "support/Logger.h"
10ad97ccf6SSam McCall #include "support/Trace.h"
11ad97ccf6SSam McCall #include "llvm/Support/Chrono.h"
1230667c96SSam McCall #include "llvm/Support/Error.h"
13ad97ccf6SSam McCall #include "llvm/Support/FormatVariadic.h"
14ad97ccf6SSam McCall #include "llvm/Support/raw_ostream.h"
15ad97ccf6SSam McCall #include <mutex>
16ad97ccf6SSam McCall
17ad97ccf6SSam McCall namespace clang {
18ad97ccf6SSam McCall namespace clangd {
19ad97ccf6SSam McCall
20ad97ccf6SSam McCall namespace {
21ad97ccf6SSam McCall Logger *L = nullptr;
22ad97ccf6SSam McCall } // namespace
23ad97ccf6SSam McCall
LoggingSession(clangd::Logger & Instance)24ad97ccf6SSam McCall LoggingSession::LoggingSession(clangd::Logger &Instance) {
25ad97ccf6SSam McCall assert(!L);
26ad97ccf6SSam McCall L = &Instance;
27ad97ccf6SSam McCall }
28ad97ccf6SSam McCall
~LoggingSession()29ad97ccf6SSam McCall LoggingSession::~LoggingSession() { L = nullptr; }
30ad97ccf6SSam McCall
logImpl(Logger::Level Level,const char * Fmt,const llvm::formatv_object_base & Message)31*65eaec9bSSam McCall void detail::logImpl(Logger::Level Level, const char *Fmt,
32ad97ccf6SSam McCall const llvm::formatv_object_base &Message) {
33ad97ccf6SSam McCall if (L)
34*65eaec9bSSam McCall L->log(Level, Fmt, Message);
35ad97ccf6SSam McCall else {
36ad97ccf6SSam McCall static std::mutex Mu;
37ad97ccf6SSam McCall std::lock_guard<std::mutex> Guard(Mu);
38ad97ccf6SSam McCall llvm::errs() << Message << "\n";
39ad97ccf6SSam McCall }
40ad97ccf6SSam McCall }
41ad97ccf6SSam McCall
debugType(const char * Filename)42ad97ccf6SSam McCall const char *detail::debugType(const char *Filename) {
43ad97ccf6SSam McCall if (const char *Slash = strrchr(Filename, '/'))
44ad97ccf6SSam McCall return Slash + 1;
45ad97ccf6SSam McCall if (const char *Backslash = strrchr(Filename, '\\'))
46ad97ccf6SSam McCall return Backslash + 1;
47ad97ccf6SSam McCall return Filename;
48ad97ccf6SSam McCall }
49ad97ccf6SSam McCall
log(Logger::Level Level,const char * Fmt,const llvm::formatv_object_base & Message)50*65eaec9bSSam McCall void StreamLogger::log(Logger::Level Level, const char *Fmt,
51ad97ccf6SSam McCall const llvm::formatv_object_base &Message) {
52ad97ccf6SSam McCall if (Level < MinLevel)
53ad97ccf6SSam McCall return;
54ad97ccf6SSam McCall llvm::sys::TimePoint<> Timestamp = std::chrono::system_clock::now();
55ad97ccf6SSam McCall trace::log(Message);
56ad97ccf6SSam McCall std::lock_guard<std::mutex> Guard(StreamMutex);
57ad97ccf6SSam McCall Logs << llvm::formatv("{0}[{1:%H:%M:%S.%L}] {2}\n", indicator(Level),
58ad97ccf6SSam McCall Timestamp, Message);
59ad97ccf6SSam McCall Logs.flush();
60ad97ccf6SSam McCall }
61ad97ccf6SSam McCall
6230667c96SSam McCall namespace {
6330667c96SSam McCall // Like llvm::StringError but with fewer options and no gratuitous copies.
6430667c96SSam McCall class SimpleStringError : public llvm::ErrorInfo<SimpleStringError> {
6530667c96SSam McCall std::error_code EC;
6630667c96SSam McCall std::string Message;
6730667c96SSam McCall
6830667c96SSam McCall public:
SimpleStringError(std::error_code EC,std::string && Message)6930667c96SSam McCall SimpleStringError(std::error_code EC, std::string &&Message)
7030667c96SSam McCall : EC(EC), Message(std::move(Message)) {}
log(llvm::raw_ostream & OS) const7130667c96SSam McCall void log(llvm::raw_ostream &OS) const override { OS << Message; }
message() const7230667c96SSam McCall std::string message() const override { return Message; }
convertToErrorCode() const7330667c96SSam McCall std::error_code convertToErrorCode() const override { return EC; }
7430667c96SSam McCall static char ID;
7530667c96SSam McCall };
7630667c96SSam McCall char SimpleStringError::ID;
7730667c96SSam McCall
7830667c96SSam McCall } // namespace
7930667c96SSam McCall
error(std::error_code EC,std::string && Msg)8030667c96SSam McCall llvm::Error detail::error(std::error_code EC, std::string &&Msg) {
8130667c96SSam McCall return llvm::make_error<SimpleStringError>(EC, std::move(Msg));
8230667c96SSam McCall }
8330667c96SSam McCall
84ad97ccf6SSam McCall } // namespace clangd
85ad97ccf6SSam McCall } // namespace clang
86