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