Skip to content

Commit

Permalink
src: check socket path before start
Browse files Browse the repository at this point in the history
PR-URL: #73
Reviewed-BY: hyj1991 <[email protected]>
  • Loading branch information
hyj1991 authored Jun 23, 2020
1 parent b2c7e64 commit 86e610b
Show file tree
Hide file tree
Showing 20 changed files with 211 additions and 58 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

Easy-Monitor v3.0 Node.js Runtime 插件,输出性能日志,并且可以进行实时的运行时状态采样。

完整部署文档https://www.yuque.com/hyj1991/easy-monitor
点击访问 [控制台 Demo](http://120.27.24.200:7443/) 进行体验,完整的性能监控部署文档https://www.yuque.com/hyj1991/easy-monitor

## I. 兼容性

Expand Down
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface XprofilerConfig {
enable_fatal_error_hook?: boolean;
patch_http?: boolean;
patch_http_timeout?: number;
check_throw?: boolean;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion lib/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const defaultConfig = {
log_type: 0,
enable_fatal_error_hook: true,
patch_http: true,
patch_http_timeout: 30 // seconds
patch_http_timeout: 30, // seconds,
check_throw: true,
};

function checkLogDirAccessiable(logdir) {
Expand Down
1 change: 1 addition & 0 deletions src/commands/simple/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ COMMAND_CALLBACK(GetXprofilerConfig) {
data["enable_fatal_error_hook"] = GetEnableFatalErrorHook();
data["patch_http"] = GetPatchHttp();
data["patch_http_timeout"] = GetPatchHttpTimeout();
data["check_throw"] = GetCheckThrow();
success(data);
}

Expand Down
4 changes: 4 additions & 0 deletions src/configure.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static bool log_format_alinode = false;
static bool enable_fatal_error_hook = true;
static bool patch_http = true;
static uint32_t patch_http_timeout = 30;
static bool check_throw = true;

void Configure(const FunctionCallbackInfo<Value> &info) {
if (!info[0]->IsObject()) {
Expand All @@ -42,6 +43,7 @@ void Configure(const FunctionCallbackInfo<Value> &info) {
CONVERT_BOOL(enable_fatal_error_hook)
CONVERT_BOOL(patch_http)
CONVERT_UINT32(patch_http_timeout)
CONVERT_BOOL(check_throw)

info.GetReturnValue().Set(New<Boolean>(true));
}
Expand All @@ -58,6 +60,7 @@ void GetConfig(const FunctionCallbackInfo<Value> &info) {
CONFIG_NATIVE_NUMBER(enable_fatal_error_hook, Boolean)
CONFIG_NATIVE_NUMBER(patch_http, Boolean)
CONFIG_NATIVE_NUMBER(patch_http_timeout, Number)
CONFIG_NATIVE_NUMBER(check_throw, Boolean)

info.GetReturnValue().Set(config);
}
Expand All @@ -72,4 +75,5 @@ DEFINE_GET_SET_FUNCTION(EnableLogUvHandles, bool, enable_log_uv_handles)
DEFINE_GET_SET_FUNCTION(EnableFatalErrorHook, bool, enable_fatal_error_hook)
DEFINE_GET_SET_FUNCTION(PatchHttp, bool, patch_http)
DEFINE_GET_SET_FUNCTION(PatchHttpTimeout, uint32_t, patch_http_timeout)
DEFINE_GET_SET_FUNCTION(CheckThrow, bool, check_throw)
} // namespace xprofiler
1 change: 1 addition & 0 deletions src/configure.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ DECLARE_GET_SET_FUNCTION(EnableLogUvHandles, bool)
DECLARE_GET_SET_FUNCTION(EnableFatalErrorHook, bool)
DECLARE_GET_SET_FUNCTION(PatchHttp, bool)
DECLARE_GET_SET_FUNCTION(PatchHttpTimeout, uint32_t)
DECLARE_GET_SET_FUNCTION(CheckThrow, bool)

// javascript accessible
void Configure(const FunctionCallbackInfo<Value> &info);
Expand Down
6 changes: 6 additions & 0 deletions src/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
#include <string>

#include "../library/writer.h"
#include "nan.h"

namespace xprofiler {
using Nan::FunctionCallbackInfo;
using std::string;
using v8::Value;

// cpu
double GetNowCpuUsage();
Expand Down Expand Up @@ -34,6 +37,9 @@ void PrintNativeStack(JSONWriter *writer);
void PrintSystemEnv(JSONWriter *writer);
void PrintResourceLimits(JSONWriter *writer);
void PrintLoadedLibraries(JSONWriter *writer);

// js binding
void CheckSocketPath(const FunctionCallbackInfo<Value> &info);
} // namespace xprofiler

#endif
45 changes: 35 additions & 10 deletions src/platform/unix/ipc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
#include "../../logger.h"

namespace xprofiler {
using Nan::FunctionCallbackInfo;
using Nan::New;
using Nan::To;
using std::string;
using v8::Boolean;
using v8::Value;

static struct sockaddr_un server_addr;
static struct sockaddr_un client_addr;
Expand All @@ -23,26 +28,46 @@ static const char module_type[] = "ipc";
shutdown(new_client_fd, SHUT_RDWR); \
close(new_client_fd);

void CreateIpcServer(void (*parsecmd)(char *)) {
// create unix domain socket
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
Error(module_type, "create server socket failed.");
return;
}

// get domain socket file name
static string GetSocketPath() {
string filename =
GetLogDir() + "/xprofiler-uds-path-" + std::to_string(getpid()) + ".sock";
return filename;
}

if (filename.length() > sizeof(server_addr.sun_path) - 1) {
static bool CheckSocketPathIllegal(bool log_error) {
string filename = GetSocketPath();
bool illegal = filename.length() > sizeof(server_addr.sun_path) - 1;
if (illegal && log_error) {
Error(module_type,
"the length of <%s> is larger than sizeof(server_addr.sun_path) - 1 "
"(which is %lu).",
filename.c_str(), sizeof(server_addr.sun_path) - 1);
}
return illegal;
}

void CheckSocketPath(const FunctionCallbackInfo<Value> &info) {
bool log_error = false;
if (info[0]->IsBoolean()) {
log_error = To<bool>(info[0]).ToChecked();
}
info.GetReturnValue().Set(New<Boolean>(!CheckSocketPathIllegal(log_error)));
}

void CreateIpcServer(void (*parsecmd)(char *)) {
// create unix domain socket
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
Error(module_type, "create server socket failed.");
return;
}

// check socket path illegal
if (CheckSocketPathIllegal(false)) return;

// get domain socket path
string filename = GetSocketPath();

Debug(module_type, "unix domain socket file name: %s.", filename.c_str());

// set server addr
Expand Down
8 changes: 8 additions & 0 deletions src/platform/win/ipc_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
#include "uv.h"

namespace xprofiler {
using Nan::FunctionCallbackInfo;
using Nan::New;
using std::string;
using std::wstring;
using v8::Boolean;
using v8::Value;

static const char module_type[] = "ipc";

Expand Down Expand Up @@ -36,6 +40,10 @@ wstring String2LPCWSTR(const string &s) {
return r;
}

void CheckSocketPath(const FunctionCallbackInfo<Value> &info) {
info.GetReturnValue().Set(New<Boolean>(true));
}

void CreateIpcServer(void (*parsecmd)(char *)) {
HANDLE named_pipe = NULL;
string lp_name_string = "\\\\.\\pipe\\" + GetLogDir() +
Expand Down
2 changes: 2 additions & 0 deletions src/xprofiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "logbypass/log.h"
#include "logger.h"
#include "nan.h"
#include "platform/platform.h"

namespace xprofiler {
using Nan::GetFunction;
Expand Down Expand Up @@ -39,6 +40,7 @@ NAN_MODULE_INIT(Initialize) {
CREATE_JS_BINDING(runLogBypass, RunLogBypass)

// commands listener
CREATE_JS_BINDING(checkSocketPath, CheckSocketPath)
CREATE_JS_BINDING(runCommandsListener, RunCommandsListener)

// set hooks
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/blocking.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if (process.env.XPROFILER_UNIT_TEST_TMP_HOMEDIR) {

process.env.XPROFILER_UNIT_TEST_SINGLE_MODULE = 'YES';

xprofiler.start();
xprofiler.start({ check_throw: false });
console.log(`[${moment().format('YYYY-MM-DD HH:mm:ss')}]`, traceid, 'blocking xprofiler() done.');

// start log bypass
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/command.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,11 @@ exports = module.exports = function (logdir) {
{ key: 'data.enable_fatal_error_hook', rule: { label: 'true', test: value => value === true } },
{ key: 'data.patch_http', rule: { label: 'true', test: value => value === true } },
{ key: 'data.patch_http_timeout', rule: /^30$/ },
{ key: 'data.check_throw', rule: { label: 'false', test: value => value === false } },
],
xprofctlRules(data) {
return [new RegExp(`^X-Profiler 当前配置\\(pid ${data.pid}\\):\n`
+ ' - check_throw: false\n'
+ ' - enable_fatal_error_hook: true\n'
+ ' - enable_log_uv_handles: true\n'
+ ` - log_dir: ${escape(logdir)}\n`
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ const configure = {
envKey: 'XPROFILER_PATCH_HTTP_TIMEOUT',
envValue: 60,
userValue: 45
},
check_throw: {
defaultValue: true,
envKey: 'XPROFILER_CHECK_THROW',
envValue: 'NO',
userValue: false
}
};

Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/non-blocking.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if (process.env.XPROFILER_UNIT_TEST_TMP_HOMEDIR) {
mm(os, 'homedir', () => process.env.XPROFILER_UNIT_TEST_TMP_HOMEDIR);
}

xprofiler();
xprofiler({ check_throw: false });

// start log bypass
xprofiler.runLogBypass();
Expand Down
63 changes: 63 additions & 0 deletions test/illegalpath.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use strict';

const os = require('os');
const mm = require('mm');
const expect = require('expect.js');
const xprofiler = require('../xprofiler');
const utils = require('./fixtures/utils');

if (os.platform() === 'win32') {
describe(`platform ${os.platform()}: check socket path illegal`, function () {
it(`should throw socket check error`, function () {
expect(true).to.be.ok();
});

it(`should console check error`, function () {
expect(true).to.be.ok();
});
});
} else {
describe(`platform ${os.platform()}: check socket path illegal`, function () {
const tmpLogdir = utils.createLogDir(`logdir_long_${new Array(100).fill('*').join('')}`);
const coreMessage = 'socket path is too long, complete log of this error can be found in';
let consoleError;
before(function () {
mm(process.env, 'XPROFILER_UNIT_TEST_SINGLE_MODULE', 'YES');
mm(process.env, 'XPROFILER_LOG_DIR', tmpLogdir);
mm(console, 'error', function (message) {
consoleError = message;
});
});

after(function () {
mm.restore();
utils.cleanDir(tmpLogdir);
});

it(`should throw socket check error: ${coreMessage}`, function () {
let error;
try {
xprofiler.start();
} catch (err) {
error = err.message;
}
expect(error).to.be.ok();
expect(consoleError).not.to.be.ok();
expect(error.includes(coreMessage)).to.be.ok();
});

it(`should console check error: ${coreMessage}`, function () {
let error;
try {
xprofiler.start({
check_throw: false
});
} catch (err) {
error = err.message;
}
expect(consoleError).to.be.ok();
expect(error).not.to.be.ok();
expect(consoleError.includes(coreMessage)).to.be.ok();
});
});
}
2 changes: 1 addition & 1 deletion test/logbypass.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const casesForLibuv = getTestCases('performance log correctly with XPROFILER_ENA
// http cases
const logdirBlockingForHttp = utils.createLogDir('log_bypass_blocking_http');
const logdirNonBlockingForHttp = utils.createLogDir('log_bypass_non_blocking_http');
const casesForHttp = getTestCases('performance log correctly XPROFILER_PATCH_HTTP=YES',
const casesForHttp = getTestCases('performance log correctly XPROFILER_PATCH_HTTP=NO',
logdirBlockingForHttp, logdirNonBlockingForHttp, { XPROFILER_PATCH_HTTP: 'NO', XPROFILER_PATCH_HTTP_TIMEOUT: 30 },
{
http: {
Expand Down
43 changes: 0 additions & 43 deletions test/platform.test.js

This file was deleted.

Loading

0 comments on commit 86e610b

Please sign in to comment.