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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "Logger.h"
10 #include "Trace.h"
11 #include "llvm/Support/Chrono.h"
12 #include "llvm/Support/FormatVariadic.h"
13 #include "llvm/Support/raw_ostream.h"
14 #include <mutex>
15
16 namespace clang {
17 namespace clangd {
18
19 namespace {
20 Logger *L = nullptr;
21 } // namespace
22
LoggingSession(clangd::Logger & Instance)23 LoggingSession::LoggingSession(clangd::Logger &Instance) {
24 assert(!L);
25 L = &Instance;
26 }
27
~LoggingSession()28 LoggingSession::~LoggingSession() { L = nullptr; }
29
log(Logger::Level Level,const llvm::formatv_object_base & Message)30 void detail::log(Logger::Level Level,
31 const llvm::formatv_object_base &Message) {
32 if (L)
33 L->log(Level, Message);
34 else {
35 static std::mutex Mu;
36 std::lock_guard<std::mutex> Guard(Mu);
37 llvm::errs() << Message << "\n";
38 }
39 }
40
debugType(const char * Filename)41 const char *detail::debugType(const char *Filename) {
42 if (const char *Slash = strrchr(Filename, '/'))
43 return Slash + 1;
44 if (const char *Backslash = strrchr(Filename, '\\'))
45 return Backslash + 1;
46 return Filename;
47 }
48
log(Logger::Level Level,const llvm::formatv_object_base & Message)49 void StreamLogger::log(Logger::Level Level,
50 const llvm::formatv_object_base &Message) {
51 if (Level < MinLevel)
52 return;
53 llvm::sys::TimePoint<> Timestamp = std::chrono::system_clock::now();
54 trace::log(Message);
55 std::lock_guard<std::mutex> Guard(StreamMutex);
56 Logs << llvm::formatv("{0}[{1:%H:%M:%S.%L}] {2}\n", indicator(Level),
57 Timestamp, Message);
58 Logs.flush();
59 }
60
61 } // namespace clangd
62 } // namespace clang
63