diff --git a/src/commands/report/node_report.cc b/src/commands/report/node_report.cc index 4465287..66ae725 100644 --- a/src/commands/report/node_report.cc +++ b/src/commands/report/node_report.cc @@ -27,7 +27,7 @@ static void WriteNodeReport(JSONWriter *writer, string location, string message, writer->json_keyvalue("pid", GetPid()); writer->json_keyvalue("location", location); writer->json_keyvalue("message", message); - writer->json_keyvalue("nodeVersion", GetGlobalNodeVersion()); + writer->json_keyvalue("nodeVersion", NODE_VERSION); writer->json_keyvalue("osVersion", GetOsVersion()); writer->json_keyvalue("loadTime", GetStartTime("%Y-%m-%d %H:%M:%S")); writer->json_keyvalue("dumpTime", ConvertTime("%Y-%m-%d %H:%M:%S")); @@ -54,4 +54,4 @@ void NodeReport::GetNodeReport(string filepath, string location, string message, WriteNodeReport(&writer, location, message, fatal_error); outfile.close(); } -} // namespace xprofiler \ No newline at end of file +} // namespace xprofiler diff --git a/src/configure.h b/src/configure.h index d623432..9e8d43a 100644 --- a/src/configure.h +++ b/src/configure.h @@ -3,6 +3,7 @@ #include "library/common.h" #include "library/error.h" +#include "logger.h" #include "nan.h" namespace xprofiler { diff --git a/src/library/common.cc b/src/library/common.cc index 9e0b781..131296e 100644 --- a/src/library/common.cc +++ b/src/library/common.cc @@ -17,23 +17,23 @@ using v8::Object; using v8::String; using v8::Value; -static time_t load_time; -static string global_node_version_string = NODE_VERSION; +namespace per_process { +time_t load_time; +} -void InitGlobalVariables() { time(&load_time); } +void InitOnceLoadTime() { time(&per_process::load_time); } unsigned long GetUptime() { time_t current_time; time(¤t_time); - return static_cast(difftime(current_time, load_time)); + return static_cast( + difftime(current_time, per_process::load_time)); } string GetStartTime(string format) { char time_string_day[32]; - struct tm *ptm = localtime(&load_time); + struct tm *ptm = localtime(&per_process::load_time); strftime(time_string_day, sizeof(time_string_day), format.c_str(), ptm); return (string)time_string_day; } - -string GetGlobalNodeVersion() { return global_node_version_string; } } // namespace xprofiler diff --git a/src/library/common.h b/src/library/common.h index 23c3a99..662ee8f 100644 --- a/src/library/common.h +++ b/src/library/common.h @@ -1,29 +1,20 @@ -#ifndef _SRC_LIBRARY_COMMON_H -#define _SRC_LIBRARY_COMMON_H +#ifndef XPROFILER_SRC_LIBRARY_COMMON_H +#define XPROFILER_SRC_LIBRARY_COMMON_H #include "json.hpp" namespace xprofiler { -using nlohmann::json; -using std::function; -using std::string; - -// xprofiler logger -enum LOG_LEVEL { LOG_INFO, LOG_ERROR, LOG_DEBUG }; -enum LOG_TYPE { LOG_TO_FILE, LOG_TO_TTL }; - -// global variables -void InitGlobalVariables(); -string GetGlobalNodeVersion(); +void InitOnceLoadTime(); // uptime unsigned long GetUptime(); -string GetStartTime(string format); +std::string GetStartTime(std::string format); // commands -#define COMMAND_CALLBACK(cb) \ - void cb(json command, string (*format)(const char *, ...), \ - function success, function error) +#define COMMAND_CALLBACK(cb) \ + void cb(nlohmann::json command, std::string (*format)(const char *, ...), \ + std::function success, \ + std::function error) } // namespace xprofiler -#endif \ No newline at end of file +#endif /* XPROFILER_SRC_LIBRARY_COMMON_H */ diff --git a/src/logger.cc b/src/logger.cc index 68e1232..c600a0b 100644 --- a/src/logger.cc +++ b/src/logger.cc @@ -10,6 +10,7 @@ #include "configure-inl.h" #include "platform/platform.h" +#include "util.h" namespace xprofiler { using Nan::New; @@ -21,17 +22,10 @@ using std::to_string; using v8::Local; using v8::String; -#define WRITET_TO_FILE(type) \ - uv_mutex_lock(&logger_mutex); \ - type##_stream.open(filepath, std::ios::app); \ - type##_stream << log; \ - type##_stream.close(); \ - uv_mutex_unlock(&logger_mutex); - -#define LOG_WITH_LEVEL(level) \ - va_list args; \ - va_start(args, format); \ - Log(LOG_LEVEL::level, log_type, format, &args); \ +#define LOG_WITH_LEVEL(level) \ + va_list args; \ + va_start(args, format); \ + Log(LOG_LEVEL::level, log_type, format, args); \ va_end(args); #define JS_LOG_WITH_LEVEL(level) \ @@ -49,12 +43,9 @@ using v8::String; static const int kMaxMessageLength = 2048; static const int kMaxFormatLength = 2048; -static uv_mutex_t logger_mutex; - -// output -static std::ofstream info_stream; -static std::ofstream error_stream; -static std::ofstream debug_stream; +namespace per_process { +uv_mutex_t logger_mutex; +} static void WriteToFile(const LOG_LEVEL output_level, char *log) { // get time of date @@ -74,19 +65,23 @@ static void WriteToFile(const LOG_LEVEL output_level, char *log) { switch (output_level) { case LOG_LEVEL::LOG_INFO: filepath += file_prefix + time_string_day + ".log"; - WRITET_TO_FILE(info) break; case LOG_LEVEL::LOG_ERROR: filepath += file_prefix + "error-" + time_string_day + ".log"; - WRITET_TO_FILE(error) break; case LOG_LEVEL::LOG_DEBUG: filepath += file_prefix + "debug-" + time_string_day + ".log"; - WRITET_TO_FILE(debug) break; default: - break; + UNREACHABLE(); + } + + uv_mutex_lock(&per_process::logger_mutex); + { + std::ofstream ostream(filepath, std::ios::app); + ostream << log; } + uv_mutex_unlock(&per_process::logger_mutex); } static void Log(const LOG_LEVEL output_level, const char *type, @@ -167,9 +162,8 @@ static void Log(const LOG_LEVEL output_level, const char *type, } } -int InitLogger() { - int rc = uv_mutex_init(&logger_mutex); - return rc; +void InitOnceLogger() { + CHECK_EQ(uv_mutex_init(&per_process::logger_mutex), 0); } /* native logger */ diff --git a/src/logger.h b/src/logger.h index 6a5e10a..d07c866 100644 --- a/src/logger.h +++ b/src/logger.h @@ -1,5 +1,5 @@ -#ifndef SRC_LOGGER_H -#define SRC_LOGGER_H +#ifndef XPROFILER_SRC_LOGGER_H +#define XPROFILER_SRC_LOGGER_H #include "library/common.h" #include "nan.h" @@ -8,7 +8,11 @@ namespace xprofiler { using Nan::FunctionCallbackInfo; using v8::Value; -int InitLogger(); +// xprofiler logger +enum LOG_LEVEL { LOG_INFO, LOG_ERROR, LOG_DEBUG }; +enum LOG_TYPE { LOG_TO_FILE, LOG_TO_TTL }; + +void InitOnceLogger(); // normal external void Info(const char *log_type, const char *format, ...); @@ -21,4 +25,4 @@ void JsError(const FunctionCallbackInfo &info); void JsDebug(const FunctionCallbackInfo &info); } // namespace xprofiler -#endif \ No newline at end of file +#endif /* XPROFILER_SRC_LOGGER_H */ diff --git a/src/util.h b/src/util.h index 3436107..8b88320 100644 --- a/src/util.h +++ b/src/util.h @@ -24,9 +24,15 @@ struct AssertionInfo { xprofiler::Assert(args); \ } while (0) +#ifdef __GNUC__ #define LIKELY(expr) __builtin_expect(!!(expr), 1) #define UNLIKELY(expr) __builtin_expect(!!(expr), 0) #define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__ +#else +#define LIKELY(expr) expr +#define UNLIKELY(expr) expr +#define PRETTY_FUNCTION_NAME "" +#endif #define STRINGIFY_(x) #x #define STRINGIFY(x) STRINGIFY_(x) @@ -72,6 +78,9 @@ struct AssertionInfo { #define DCHECK_IMPLIES(a, b) #endif +#define UNREACHABLE(...) \ + ERROR_AND_ABORT("Unreachable code reached" __VA_OPT__(": ") __VA_ARGS__) + // Convenience wrapper around v8::String::NewFromOneByte inline v8::Local OneByteString(v8::Isolate* isolate, const char* data, int length = -1); diff --git a/src/xprofiler.cc b/src/xprofiler.cc index 23f7f07..3c316e5 100644 --- a/src/xprofiler.cc +++ b/src/xprofiler.cc @@ -15,43 +15,42 @@ using Nan::Set; using v8::FunctionTemplate; using v8::String; +NODE_C_CTOR(Main) { + // init global variables + InitOnceLoadTime(); + InitOnceLogger(); +} + #define CREATE_JS_BINDING(js_func, native_func) \ Set(target, New(#js_func).ToLocalChecked(), \ - GetFunction(New(native_func)).ToLocalChecked()); + GetFunction(New(native_func)).ToLocalChecked()) NAN_MODULE_INIT(Initialize) { - // init global variables - InitGlobalVariables(); - - // init logger - int rc = InitLogger(); - if (rc != 0) return; - // config - CREATE_JS_BINDING(configure, Configure) - CREATE_JS_BINDING(getConfig, GetConfig) + CREATE_JS_BINDING(configure, Configure); + CREATE_JS_BINDING(getConfig, GetConfig); // js logger - CREATE_JS_BINDING(info, JsInfo) - CREATE_JS_BINDING(error, JsError) - CREATE_JS_BINDING(debug, JsDebug) + CREATE_JS_BINDING(info, JsInfo); + CREATE_JS_BINDING(error, JsError); + CREATE_JS_BINDING(debug, JsDebug); // performance log - CREATE_JS_BINDING(runLogBypass, RunLogBypass) + CREATE_JS_BINDING(runLogBypass, RunLogBypass); // commands listener - CREATE_JS_BINDING(checkSocketPath, CheckSocketPath) - CREATE_JS_BINDING(runCommandsListener, RunCommandsListener) + CREATE_JS_BINDING(checkSocketPath, CheckSocketPath); + CREATE_JS_BINDING(runCommandsListener, RunCommandsListener); // set hooks - CREATE_JS_BINDING(setHooks, SetHooks) + CREATE_JS_BINDING(setHooks, SetHooks); // http status - CREATE_JS_BINDING(addLiveRequest, AddLiveRequest) - CREATE_JS_BINDING(addCloseRequest, AddCloseRequest) - CREATE_JS_BINDING(addSentRequest, AddSentRequest) - CREATE_JS_BINDING(addRequestTimeout, AddRequestTimeout) - CREATE_JS_BINDING(addHttpStatusCode, AddHttpStatusCode) + CREATE_JS_BINDING(addLiveRequest, AddLiveRequest); + CREATE_JS_BINDING(addCloseRequest, AddCloseRequest); + CREATE_JS_BINDING(addSentRequest, AddSentRequest); + CREATE_JS_BINDING(addRequestTimeout, AddRequestTimeout); + CREATE_JS_BINDING(addHttpStatusCode, AddHttpStatusCode); } // TODO(legendecas): declare context aware when ready.