Skip to content

Commit 9e1039f

Browse files
authored
refactor: improve logging (#301)
1 parent 8a2ef62 commit 9e1039f

File tree

20 files changed

+189
-195
lines changed

20 files changed

+189
-195
lines changed

bin/clice.cc

Lines changed: 19 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,6 @@ cl::opt<unsigned int> port{
4848
cl::desc("The port to connect to"),
4949
};
5050

51-
cl::opt<std::string> resource_dir{
52-
"resource-dir",
53-
cl::cat(category),
54-
cl::value_desc("path"),
55-
cl::desc(R"(The path of the clang resource directory, default is "../../lib/clang/version")"),
56-
};
57-
5851
cl::opt<logging::ColorMode> log_color{
5952
"log-color",
6053
cl::cat(category),
@@ -69,75 +62,43 @@ cl::opt<logging::ColorMode> log_color{
6962
cl::opt<logging::Level> log_level{
7063
"log-level",
7164
cl::cat(category),
72-
cl::value_desc("trace|debug|info|warn|fatal"),
65+
cl::value_desc("trace|debug|info|warn|error"),
7366
cl::init(logging::Level::info),
7467
cl::values(clEnumValN(logging::Level::trace, "trace", ""),
7568
clEnumValN(logging::Level::debug, "debug", ""),
7669
clEnumValN(logging::Level::info, "info", ""),
7770
clEnumValN(logging::Level::warn, "warn", ""),
78-
clEnumValN(logging::Level::err, "fatal", "")),
71+
clEnumValN(logging::Level::err, "error", ""),
72+
clEnumValN(logging::Level::off, "off", "")),
7973
cl::desc("The log level, default is info"),
8074
};
8175

82-
void init_log() {
83-
using namespace logging;
84-
options.color = log_color;
85-
options.level = log_level;
86-
logging::create_stderr_logger("clice", logging::options);
87-
}
88-
89-
/// Check the command line arguments and initialize the clice.
90-
bool check_arguments(int argc, const char** argv) {
91-
/// Hide unrelated options.
92-
cl::HideUnrelatedOptions(category);
76+
} // namespace
9377

94-
// Set version printer and parse command line options
78+
int main(int argc, const char** argv) {
79+
llvm::InitLLVM guard(argc, argv);
80+
llvm::setBugReportMsg(
81+
"Please report bugs to https://github.com/clice-io/clice/issues and include the crash backtrace");
9582
cl::SetVersionPrinter([](llvm::raw_ostream& os) {
9683
os << std::format("clice version: {}\nllvm version: {}\n",
9784
clice::config::version,
9885
clice::config::llvm_version);
9986
});
87+
cl::HideUnrelatedOptions(category);
10088
cl::ParseCommandLineOptions(argc,
10189
argv,
10290
"clice is a new generation of language server for C/C++");
10391

104-
init_log();
92+
logging::options.color = log_color;
93+
logging::options.level = log_level;
94+
logging::stderr_logger("clice", logging::options);
10595

106-
for(int i = 0; i < argc; ++i) {
107-
logging::info("argv[{}] = {}", i, argv[i]);
96+
if(auto result = fs::init_resource_dir(argv[0]); !result) {
97+
LOGGING_FATAL("Cannot find default resource directory, because {}", result.error());
10898
}
10999

110-
// Initialize resource directory
111-
if(resource_dir.empty()) {
112-
logging::info("No resource directory specified, using default resource directory");
113-
// Try to initialize default resource directory
114-
if(auto result = fs::init_resource_dir(argv[0]); !result) {
115-
logging::warn("Cannot find default resource directory, because {}", result.error());
116-
return false;
117-
}
118-
} else {
119-
// Set and check the specified resource directory
120-
fs::resource_dir = resource_dir.getValue();
121-
if(fs::exists(fs::resource_dir)) {
122-
logging::info("Resource directory found: {}", fs::resource_dir);
123-
} else {
124-
logging::warn("Resource directory not found: {}", fs::resource_dir);
125-
return false;
126-
}
127-
}
128-
129-
return true;
130-
}
131-
132-
} // namespace
133-
134-
int main(int argc, const char** argv) {
135-
llvm::InitLLVM guard(argc, argv);
136-
llvm::setBugReportMsg(
137-
"Please report bugs to https://github.com/clice-io/clice/issues and include the crash backtrace");
138-
139-
if(!check_arguments(argc, argv)) {
140-
return 1;
100+
for(int i = 0; i < argc; ++i) {
101+
LOGGING_INFO("argv[{}] = {}", i, argv[i]);
141102
}
142103

143104
async::init();
@@ -151,13 +112,13 @@ int main(int argc, const char** argv) {
151112
switch(mode) {
152113
case Mode::Pipe: {
153114
async::net::listen(loop);
154-
logging::info("Server starts listening on stdin/stdout");
115+
LOGGING_INFO("Server starts listening on stdin/stdout");
155116
break;
156117
}
157118

158119
case Mode::Socket: {
159120
async::net::listen(host.c_str(), port, loop);
160-
logging::info("Server starts listening on {}:{}", host.getValue(), port.getValue());
121+
LOGGING_INFO("Server starts listening on {}:{}", host.getValue(), port.getValue());
161122
break;
162123
}
163124

@@ -169,7 +130,7 @@ int main(int argc, const char** argv) {
169130

170131
async::run();
171132

172-
logging::info("clice exit normally!");
133+
LOGGING_INFO("clice exit normally!");
173134

174135
return 0;
175136
}

bin/unit_tests.cc

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace {
1818

1919
namespace cl = llvm::cl;
2020

21-
cl::OptionCategory unittest_category("Clice Unittest Options");
21+
cl::OptionCategory unittest_category("clice Unittest Options");
2222

2323
cl::opt<std::string> test_dir{
2424
"test-dir",
@@ -28,12 +28,6 @@ cl::opt<std::string> test_dir{
2828
cl::cat(unittest_category),
2929
};
3030

31-
cl::opt<std::string> resource_dir{
32-
"resource-dir",
33-
cl::desc("Resource dir path"),
34-
cl::cat(unittest_category),
35-
};
36-
3731
cl::opt<std::string> test_filter{
3832
"test-filter",
3933
cl::desc("A glob pattern to run subset of tests"),
@@ -190,21 +184,17 @@ int main(int argc, const char* argv[]) {
190184
llvm::cl::HideUnrelatedOptions(unittest_category);
191185
llvm::cl::ParseCommandLineOptions(argc, argv, "clice test\n");
192186

193-
logging::create_stderr_logger("clice", logging::options);
187+
logging::stderr_logger("clice", logging::options);
194188

195189
if(!test_filter.empty()) {
196190
if(auto result = GlobPattern::create(test_filter)) {
197191
pattern.emplace(std::move(*result));
198192
}
199193
}
200194

201-
if(!resource_dir.empty()) {
202-
fs::resource_dir = resource_dir;
203-
} else {
204-
if(auto result = fs::init_resource_dir(argv[0]); !result) {
205-
std::println("Failed to get resource directory, because {}", result.error());
206-
return 1;
207-
}
195+
if(auto result = fs::init_resource_dir(argv[0]); !result) {
196+
std::println("Failed to get resource directory, because {}", result.error());
197+
return 1;
208198
}
209199

210200
using namespace clice::testing;

include/Support/Format.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,31 @@ template <>
7373
struct std::formatter<clice::json::Value> : std::formatter<llvm::StringRef> {
7474
using Base = std::formatter<llvm::StringRef>;
7575

76+
int indent = 0;
77+
7678
template <typename ParseContext>
7779
constexpr auto parse(ParseContext& ctx) {
78-
return Base::parse(ctx);
80+
auto it = ctx.begin();
81+
auto end = ctx.end();
82+
if(it == end) {
83+
return it;
84+
}
85+
86+
int parsed_indent = 0;
87+
while(it != end && *it >= '0' && *it <= '9') {
88+
parsed_indent = parsed_indent * 10 + (*it - '0');
89+
++it;
90+
}
91+
indent = parsed_indent;
92+
93+
return it;
7994
}
8095

8196
template <typename FormatContext>
8297
auto format(const clice::json::Value& value, FormatContext& ctx) const {
8398
llvm::SmallString<128> buffer;
8499
llvm::raw_svector_ostream os{buffer};
85-
os << value;
100+
llvm::json::OStream(os, indent).value(value);
86101
return Base::format(buffer, ctx);
87102
}
88103
};

include/Support/Logging.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@ using Level = spdlog::level::level_enum;
99
using ColorMode = spdlog::color_mode;
1010

1111
struct Options {
12+
/// The logging level.
1213
Level level = Level::info;
14+
15+
/// The logging color.
1316
ColorMode color = ColorMode::automatic;
17+
18+
/// If enable, we will record the logs of console sink and replay it
19+
/// when create a new sink,
20+
bool replay_console = true;
1421
};
1522

1623
extern Options options;
1724

18-
void create_stderr_logger(std::string_view name, const Options& options);
25+
void stderr_logger(std::string_view name, const Options& options);
1926

20-
void create_file_loggger(std::string_view name, std::string_view dir, const Options& options);
27+
void file_loggger(std::string_view name, std::string_view dir, const Options& options);
2128

2229
template <typename... Args>
2330
struct logging_rformat {
@@ -72,10 +79,27 @@ void warn(logging_format<Args...> fmt, Args&&... args) {
7279
}
7380

7481
template <typename... Args>
75-
void fatal [[noreturn]] (logging_format<Args...> fmt, Args&&... args) {
82+
void err(logging_format<Args...> fmt, Args&&... args) {
7683
logging::log(spdlog::level::err, fmt.location, fmt.str, std::forward<Args>(args)...);
84+
}
85+
86+
template <typename... Args>
87+
void critical [[noreturn]] (logging_format<Args...> fmt, Args&&... args) {
88+
logging::log(spdlog::level::critical, fmt.location, fmt.str, std::forward<Args>(args)...);
7789
spdlog::shutdown();
7890
std::exit(1);
7991
}
8092

8193
} // namespace clice::logging
94+
95+
#define LOGGING_MESSAGE(name, fmt, ...) \
96+
if(clice::logging::options.level <= clice::logging::Level::name) { \
97+
clice::logging::name(fmt __VA_OPT__(, ) __VA_ARGS__); \
98+
}
99+
100+
#define LOGGING_TRACE(fmt, ...) LOGGING_MESSAGE(trace, fmt, __VA_ARGS__)
101+
#define LOGGING_DEBUG(fmt, ...) LOGGING_MESSAGE(debug, fmt, __VA_ARGS__)
102+
#define LOGGING_INFO(fmt, ...) LOGGING_MESSAGE(info, fmt, __VA_ARGS__)
103+
#define LOGGING_WARN(fmt, ...) LOGGING_MESSAGE(warn, fmt, __VA_ARGS__)
104+
#define LOGGING_ERROR(fmt, ...) LOGGING_MESSAGE(err, fmt, __VA_ARGS__)
105+
#define LOGGING_FATAL(fmt, ...) clice::logging::critical(fmt __VA_OPT__(, ) __VA_ARGS__);

src/AST/Selection.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@
2424

2525
namespace clice {
2626

27-
#ifdef NDEBUG
28-
#define LOGGING_DEBUG(...)
29-
#else
30-
#define LOGGING_DEBUG(...) logging::debug(__VA_ARGS__)
31-
#endif
32-
3327
namespace {
3428

3529
using Node = SelectionTree::Node;

src/Async/FileSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ handle::~handle() {
122122
uv_fs_t request;
123123
int error = uv_fs_close(async::loop, &request, file, nullptr);
124124
if(error < 0) {
125-
logging::warn("Failed to close file: {}", uv_strerror(error));
125+
LOGGING_WARN("Failed to close file: {}", uv_strerror(error));
126126
}
127127
uv_fs_req_cleanup(&request);
128128
}

src/Async/Network.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
3030

3131
/// If an error occurred while reading, we can't continue.
3232
if(nread < 0) [[unlikely]] {
33-
logging::fatal("An error occurred while reading: {0}", uv_strerror(nread));
33+
LOGGING_FATAL("An error occurred while reading: {0}", uv_strerror(nread));
3434
}
3535

3636
/// We have at most one connection and use default event loop. So there is no data race
@@ -57,7 +57,7 @@ void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
5757
task.dispose();
5858
} else {
5959
/// If the message is invalid, we can't continue.
60-
logging::fatal("Unexpected JSON input: {0}", result);
60+
LOGGING_FATAL("Unexpected JSON input: {0}", result);
6161
}
6262

6363
/// Remove the processed message from the buffer.
@@ -130,7 +130,7 @@ struct write {
130130

131131
uv_write(&req, writer, buf, 2, [](uv_write_t* req, int status) {
132132
if(status < 0) {
133-
logging::fatal("An error occurred while writing: {0}", uv_strerror(status));
133+
LOGGING_FATAL("An error occurred while writing: {0}", uv_strerror(status));
134134
}
135135

136136
auto& awaiter = uv_cast<struct write>(req);

src/Async/libuv.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ const std::error_category& category() {
2929
/// Use source_location to log the file, line, and function name where the error occurred.
3030
void uv_check_result(const int result, const std::source_location location) {
3131
if(result < 0) {
32-
logging::warn("libuv error: {}", uv_strerror(result));
33-
logging::warn("At {}:{}:{}",
34-
location.file_name(),
35-
location.line(),
36-
location.function_name());
32+
LOGGING_WARN("libuv error: {}", uv_strerror(result));
33+
LOGGING_WARN("At {}:{}:{}",
34+
location.file_name(),
35+
location.line(),
36+
location.function_name());
3737
}
3838
}
3939

0 commit comments

Comments
 (0)