mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-23 14:56:07 +08:00
修复 shell 变量初始化检查,更新 sentry 版本
This commit is contained in:
parent
a743aa8115
commit
af5de8372c
|
@ -1,3 +1,4 @@
|
||||||
|
import './loaders/sentry'
|
||||||
import 'reflect-metadata'; // We need this in order to use @Decorators
|
import 'reflect-metadata'; // We need this in order to use @Decorators
|
||||||
import config from './config';
|
import config from './config';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
@ -10,8 +11,6 @@ async function startServer() {
|
||||||
|
|
||||||
await require('./loaders/initFile').default();
|
await require('./loaders/initFile').default();
|
||||||
|
|
||||||
await require('./loaders/sentry').default({ expressApp: app });
|
|
||||||
|
|
||||||
await require('./loaders/app').default({ expressApp: app });
|
await require('./loaders/app').default({ expressApp: app });
|
||||||
|
|
||||||
const server = app
|
const server = app
|
||||||
|
|
|
@ -461,7 +461,7 @@ export async function parseVersion(path: string): Promise<IVersion> {
|
||||||
return load(await fs.readFile(path, 'utf8')) as IVersion;
|
return load(await fs.readFile(path, 'utf8')) as IVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseContentVersion(content: string): Promise<IVersion> {
|
export function parseContentVersion(content: string): IVersion {
|
||||||
return load(content) as IVersion;
|
return load(content) as IVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,8 @@ export default ({ app }: { app: Application }) => {
|
||||||
|
|
||||||
app.use(errors());
|
app.use(errors());
|
||||||
|
|
||||||
|
Sentry.setupExpressErrorHandler(app);
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
(
|
(
|
||||||
err: Error & { status: number },
|
err: Error & { status: number },
|
||||||
|
@ -178,8 +180,6 @@ export default ({ app }: { app: Application }) => {
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction,
|
next: NextFunction,
|
||||||
) => {
|
) => {
|
||||||
Sentry.captureException(err);
|
|
||||||
|
|
||||||
res.status(err.status || 500);
|
res.status(err.status || 500);
|
||||||
res.json({
|
res.json({
|
||||||
code: err.status || 500,
|
code: err.status || 500,
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import { Application } from 'express';
|
|
||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
|
import { nodeProfilingIntegration } from '@sentry/profiling-node';
|
||||||
import Logger from './logger';
|
import Logger from './logger';
|
||||||
import config from '../config';
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { parseVersion } from '../config/util';
|
import config from '../config';
|
||||||
|
import { parseContentVersion } from '../config/util';
|
||||||
|
|
||||||
export default async ({ expressApp }: { expressApp: Application }) => {
|
let version = '1.0.0';
|
||||||
const { version } = await parseVersion(config.versionFile);
|
try {
|
||||||
|
const content = fs.readFileSync(config.versionFile, 'utf-8');
|
||||||
|
({ version } = parseContentVersion(content));
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
ignoreErrors: [
|
ignoreErrors: [
|
||||||
/SequelizeUniqueConstraintError/i,
|
/SequelizeUniqueConstraintError/i,
|
||||||
/Validation error/i,
|
/Validation error/i,
|
||||||
|
@ -16,17 +19,10 @@ export default async ({ expressApp }: { expressApp: Application }) => {
|
||||||
/celebrate request validation failed/i,
|
/celebrate request validation failed/i,
|
||||||
],
|
],
|
||||||
dsn: 'https://8b5c84cfef3e22541bc84de0ed00497b@o1098464.ingest.sentry.io/6122819',
|
dsn: 'https://8b5c84cfef3e22541bc84de0ed00497b@o1098464.ingest.sentry.io/6122819',
|
||||||
integrations: [
|
integrations: [nodeProfilingIntegration()],
|
||||||
new Sentry.Integrations.Http({ tracing: true }),
|
tracesSampleRate: 0.5,
|
||||||
new Sentry.Integrations.Express({ app: expressApp }),
|
|
||||||
],
|
|
||||||
tracesSampleRate: 0.8,
|
|
||||||
release: version,
|
release: version,
|
||||||
});
|
});
|
||||||
|
|
||||||
expressApp.use(Sentry.Handlers.requestHandler());
|
Logger.info('✌️ Sentry loaded');
|
||||||
expressApp.use(Sentry.Handlers.tracingHandler());
|
console.log('✌️ Sentry loaded');
|
||||||
|
|
||||||
Logger.info('✌️ Sentry loaded');
|
|
||||||
console.log('✌️ Sentry loaded');
|
|
||||||
};
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ export default async ({ server }: { server: Server }) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const { token = '', tokens = {} } = safeJSONParse(data);
|
const { token = '', tokens = {} } = safeJSONParse(data);
|
||||||
if (headerToken === token || tokens[platform] === headerToken) {
|
if (headerToken === token || tokens[platform] === headerToken) {
|
||||||
conn.write(JSON.stringify({ type: 'ping', message: 'hanhh' }));
|
|
||||||
sockService.addClient(conn);
|
sockService.addClient(conn);
|
||||||
|
|
||||||
conn.on('data', (message) => {
|
conn.on('data', (message) => {
|
||||||
|
@ -33,8 +32,6 @@ export default async ({ server }: { server: Server }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
conn.write(JSON.stringify({ type: 'ping', message: 'whyour' }));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ app.get('/api/health', (req, res) => {
|
||||||
|
|
||||||
app
|
app
|
||||||
.listen(config.publicPort, '0.0.0.0', async () => {
|
.listen(config.publicPort, '0.0.0.0', async () => {
|
||||||
await require('./loaders/sentry').default({ expressApp: app });
|
|
||||||
await require('./loaders/db').default();
|
await require('./loaders/db').default();
|
||||||
|
|
||||||
Logger.debug(`✌️ 公共服务启动成功!`);
|
Logger.debug(`✌️ 公共服务启动成功!`);
|
||||||
|
|
|
@ -266,7 +266,7 @@ export default class SystemService {
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
lastVersionContent = await parseContentVersion(result.body);
|
lastVersionContent = parseContentVersion(result.body);
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
|
|
||||||
if (!lastVersionContent) {
|
if (!lastVersionContent) {
|
||||||
|
|
10
package.json
10
package.json
|
@ -2,11 +2,11 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "concurrently -n w: npm:start:*",
|
"start": "concurrently -n w: npm:start:*",
|
||||||
"start:front": "max dev",
|
|
||||||
"start:back": "nodemon",
|
|
||||||
"start:update": "ts-node -P tsconfig.back.json ./back/update.ts",
|
"start:update": "ts-node -P tsconfig.back.json ./back/update.ts",
|
||||||
"start:public": "ts-node -P tsconfig.back.json ./back/public.ts",
|
"start:public": "ts-node -P tsconfig.back.json ./back/public.ts",
|
||||||
"start:rpc": "ts-node -P tsconfig.back.json ./back/schedule/index.ts",
|
"start:rpc": "ts-node -P tsconfig.back.json ./back/schedule/index.ts",
|
||||||
|
"start:back": "nodemon",
|
||||||
|
"start:front": "max dev",
|
||||||
"build:front": "max build",
|
"build:front": "max build",
|
||||||
"build:back": "tsc -p tsconfig.back.json",
|
"build:back": "tsc -p tsconfig.back.json",
|
||||||
"panel": "npm run build:back && node static/build/app.js",
|
"panel": "npm run build:back && node static/build/app.js",
|
||||||
|
@ -59,7 +59,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@grpc/grpc-js": "^1.8.13",
|
"@grpc/grpc-js": "^1.8.13",
|
||||||
"@otplib/preset-default": "^12.0.1",
|
"@otplib/preset-default": "^12.0.1",
|
||||||
"@sentry/node": "^7.12.1",
|
"@sentry/node": "^8.26.0",
|
||||||
|
"@sentry/profiling-node": "8.26.0",
|
||||||
"body-parser": "^1.19.2",
|
"body-parser": "^1.19.2",
|
||||||
"celebrate": "^15.0.1",
|
"celebrate": "^15.0.1",
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
|
@ -107,7 +108,8 @@
|
||||||
"@ant-design/pro-layout": "6.38.22",
|
"@ant-design/pro-layout": "6.38.22",
|
||||||
"@monaco-editor/react": "4.2.1",
|
"@monaco-editor/react": "4.2.1",
|
||||||
"@react-hook/resize-observer": "^1.2.6",
|
"@react-hook/resize-observer": "^1.2.6",
|
||||||
"@sentry/react": "^7.12.1",
|
"react-router-dom": "6.26.1",
|
||||||
|
"@sentry/react": "^8.26.0",
|
||||||
"@types/body-parser": "^1.19.2",
|
"@types/body-parser": "^1.19.2",
|
||||||
"@types/cors": "^2.8.12",
|
"@types/cors": "^2.8.12",
|
||||||
"@types/cross-spawn": "^6.0.2",
|
"@types/cross-spawn": "^6.0.2",
|
||||||
|
|
807
pnpm-lock.yaml
807
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -817,7 +817,7 @@ function wePlusBotNotify(text, desp) {
|
||||||
const { WE_PLUS_BOT_TOKEN, WE_PLUS_BOT_RECEIVER, WE_PLUS_BOT_VERSION } =
|
const { WE_PLUS_BOT_TOKEN, WE_PLUS_BOT_RECEIVER, WE_PLUS_BOT_VERSION } =
|
||||||
push_config;
|
push_config;
|
||||||
if (WE_PLUS_BOT_TOKEN) {
|
if (WE_PLUS_BOT_TOKEN) {
|
||||||
const template = 'txt';
|
let template = 'txt';
|
||||||
if (desp.length > 800) {
|
if (desp.length > 800) {
|
||||||
desp = desp.replace(/[\n\r]/g, '<br>');
|
desp = desp.replace(/[\n\r]/g, '<br>');
|
||||||
template = 'html';
|
template = 'html';
|
||||||
|
|
|
@ -100,7 +100,7 @@ run_normal() {
|
||||||
if [[ $isJsOrPythonFile == 'false' ]]; then
|
if [[ $isJsOrPythonFile == 'false' ]]; then
|
||||||
clear_non_sh_env
|
clear_non_sh_env
|
||||||
fi
|
fi
|
||||||
$timeoutCmd $which_program $file_param "${script_params[@]}"
|
$timeoutCmd $which_program $file_param "${script_params[@]:-''}"
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_env_split() {
|
handle_env_split() {
|
||||||
|
@ -143,7 +143,7 @@ run_concurrent() {
|
||||||
export "${env_param}=${array[$i - 1]}"
|
export "${env_param}=${array[$i - 1]}"
|
||||||
clear_non_sh_env
|
clear_non_sh_env
|
||||||
fi
|
fi
|
||||||
eval envParam="${env_param}" numParam="${i}" $timeoutCmd $which_program $file_param "${script_params[@]}" &>$single_log_path &
|
eval envParam="${env_param}" numParam="${i}" $timeoutCmd $which_program $file_param "${script_params[@]:-''}" &>$single_log_path &
|
||||||
done
|
done
|
||||||
|
|
||||||
wait
|
wait
|
||||||
|
@ -188,7 +188,7 @@ run_designated() {
|
||||||
file_param=${file_param/$relative_path\//}
|
file_param=${file_param/$relative_path\//}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
envParam="${env_param}" numParam="${num_param}" $timeoutCmd $which_program $file_param "${script_params[@]}"
|
envParam="${env_param}" numParam="${num_param}" $timeoutCmd $which_program $file_param "${script_params[@]:-''}"
|
||||||
}
|
}
|
||||||
|
|
||||||
## 运行其他命令
|
## 运行其他命令
|
||||||
|
@ -210,15 +210,15 @@ run_else() {
|
||||||
|
|
||||||
check_file() {
|
check_file() {
|
||||||
isJsOrPythonFile="false"
|
isJsOrPythonFile="false"
|
||||||
if [[ $1 == *.js ]] || [[ $1 == *.py ]] || [[ $1 == *.pyc ]] || [[ $1 == *.ts ]]; then
|
if [[ $1 == *.js ]] || [[ $1 == *.mjs ]] || [[ $1 == *.py ]] || [[ $1 == *.pyc ]] || [[ $1 == *.ts ]]; then
|
||||||
isJsOrPythonFile="true"
|
isJsOrPythonFile="true"
|
||||||
fi
|
fi
|
||||||
if [[ -f $file_env ]]; then
|
if [[ -f $file_env ]]; then
|
||||||
get_env_array
|
get_env_array
|
||||||
if [[ $isJsOrPythonFile == 'true' ]]; then
|
if [[ $isJsOrPythonFile == 'true' ]]; then
|
||||||
PREV_NODE_OPTIONS="${NODE_OPTIONS}"
|
PREV_NODE_OPTIONS="${NODE_OPTIONS:=}"
|
||||||
PREV_PYTHONPATH="${PYTHONPATH}"
|
PREV_PYTHONPATH="${PYTHONPATH:=}"
|
||||||
if [[ $1 == *.js ]] || [[ $1 == *.ts ]]; then
|
if [[ $1 == *.js ]] || [[ $1 == *.ts ]] || [[ $1 == *.mjs ]]; then
|
||||||
export NODE_OPTIONS="${NODE_OPTIONS} -r ${file_preload_js}"
|
export NODE_OPTIONS="${NODE_OPTIONS} -r ${file_preload_js}"
|
||||||
else
|
else
|
||||||
export PYTHONPATH="${PYTHONPATH}:${dir_preload}:${dir_config}"
|
export PYTHONPATH="${PYTHONPATH}:${dir_preload}:${dir_config}"
|
||||||
|
|
|
@ -5,7 +5,7 @@ export dir_root=$QL_DIR
|
||||||
export dir_tmp=$dir_root/.tmp
|
export dir_tmp=$dir_root/.tmp
|
||||||
export dir_data=$dir_root/data
|
export dir_data=$dir_root/data
|
||||||
|
|
||||||
if [[ $QL_DATA_DIR ]]; then
|
if [[ ${QL_DATA_DIR:=} ]]; then
|
||||||
export dir_data="${QL_DATA_DIR%/}"
|
export dir_data="${QL_DATA_DIR%/}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ import_config() {
|
||||||
command_timeout_time=${CommandTimeoutTime:-""}
|
command_timeout_time=${CommandTimeoutTime:-""}
|
||||||
file_extensions=${RepoFileExtensions:-"js py"}
|
file_extensions=${RepoFileExtensions:-"js py"}
|
||||||
proxy_url=${ProxyUrl:-""}
|
proxy_url=${ProxyUrl:-""}
|
||||||
current_branch=${QL_BRANCH}
|
current_branch=${QL_BRANCH:-""}
|
||||||
|
|
||||||
if [[ -n "${DefaultCronRule}" ]]; then
|
if [[ -n "${DefaultCronRule}" ]]; then
|
||||||
default_cron="${DefaultCronRule}"
|
default_cron="${DefaultCronRule}"
|
||||||
|
@ -461,7 +461,7 @@ run_task_before() {
|
||||||
run_task_after() {
|
run_task_after() {
|
||||||
. $file_task_after "$@"
|
. $file_task_after "$@"
|
||||||
|
|
||||||
if [[ $task_after ]]; then
|
if [[ ${task_after:=} ]]; then
|
||||||
echo -e "\n执行后置命令\n"
|
echo -e "\n执行后置命令\n"
|
||||||
eval "$task_after" "$@"
|
eval "$task_after" "$@"
|
||||||
echo -e "\n执行后置命令结束"
|
echo -e "\n执行后置命令结束"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
## 导入通用变量与函数
|
|
||||||
dir_shell=$QL_DIR/shell
|
dir_shell=$QL_DIR/shell
|
||||||
. $dir_shell/share.sh
|
. $dir_shell/share.sh
|
||||||
. $dir_shell/api.sh
|
. $dir_shell/api.sh
|
||||||
|
@ -11,7 +10,6 @@ single_hanle() {
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
## 选择python3还是node
|
|
||||||
define_program() {
|
define_program() {
|
||||||
local file_param=$1
|
local file_param=$1
|
||||||
if [[ $file_param == *.js ]] || [[ $file_param == *.mjs ]]; then
|
if [[ $file_param == *.js ]] || [[ $file_param == *.mjs ]]; then
|
||||||
|
@ -34,7 +32,7 @@ handle_log_path() {
|
||||||
file_param="task"
|
file_param="task"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $ID ]]; then
|
if [[ -z ${ID:=} ]]; then
|
||||||
ID=$(cat $list_crontab_user | grep -E "$cmd_task.* $file_param" | perl -pe "s|.*ID=(.*) $cmd_task.* $file_param\.*|\1|" | head -1 | awk -F " " '{print $1}')
|
ID=$(cat $list_crontab_user | grep -E "$cmd_task.* $file_param" | perl -pe "s|.*ID=(.*) $cmd_task.* $file_param\.*|\1|" | head -1 | awk -F " " '{print $1}')
|
||||||
fi
|
fi
|
||||||
local suffix=""
|
local suffix=""
|
||||||
|
@ -62,17 +60,17 @@ handle_log_path() {
|
||||||
log_dir="${log_dir_tmp%.*}${suffix}"
|
log_dir="${log_dir_tmp%.*}${suffix}"
|
||||||
log_path="$log_dir/$log_time.log"
|
log_path="$log_dir/$log_time.log"
|
||||||
|
|
||||||
if [[ $real_log_path ]]; then
|
if [[ ${real_log_path:=} ]]; then
|
||||||
log_path="$real_log_path"
|
log_path="$real_log_path"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cmd="2>&1 | tee -a $dir_log/$log_path"
|
cmd="2>&1 | tee -a $dir_log/$log_path"
|
||||||
make_dir "$dir_log/$log_dir"
|
make_dir "$dir_log/$log_dir"
|
||||||
if [[ "$no_tee" == "true" ]]; then
|
if [[ "${no_tee:=}" == "true" ]]; then
|
||||||
cmd=">> $dir_log/$log_path 2>&1"
|
cmd=">> $dir_log/$log_path 2>&1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$real_time" == "true" ]]; then
|
if [[ "${real_time:=}" == "true" ]]; then
|
||||||
cmd=""
|
cmd=""
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -124,8 +122,8 @@ while getopts ":lm:" opt; do
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
[[ $show_log ]] && shift $(($OPTIND - 1))
|
[[ ${show_log:=} ]] && shift $(($OPTIND - 1))
|
||||||
if [[ $max_time ]]; then
|
if [[ ${max_time:=} ]]; then
|
||||||
shift $(($OPTIND - 1))
|
shift $(($OPTIND - 1))
|
||||||
command_timeout_time="$max_time"
|
command_timeout_time="$max_time"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,27 +1,40 @@
|
||||||
import * as Sentry from '@sentry/react';
|
import * as Sentry from '@sentry/react';
|
||||||
import { loader } from '@monaco-editor/react';
|
import { loader } from '@monaco-editor/react';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import {
|
||||||
|
createRoutesFromChildren,
|
||||||
|
matchRoutes,
|
||||||
|
useLocation,
|
||||||
|
useNavigationType,
|
||||||
|
} from 'react-router-dom';
|
||||||
|
|
||||||
export function init(version: string) {
|
export function init(version: string) {
|
||||||
// sentry监控 init
|
// sentry监控 init
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: 'https://49b9ad1a6201bfe027db296ab7c6d672@o1098464.ingest.sentry.io/6122818',
|
dsn: 'https://49b9ad1a6201bfe027db296ab7c6d672@o1098464.ingest.sentry.io/6122818',
|
||||||
integrations: [
|
integrations: [
|
||||||
new Sentry.BrowserTracing({
|
Sentry.reactRouterV6BrowserTracingIntegration({
|
||||||
shouldCreateSpanForRequest(url) {
|
useEffect,
|
||||||
return !url.includes('/api/ws') && !url.includes('/api/static');
|
useLocation,
|
||||||
},
|
useNavigationType,
|
||||||
|
createRoutesFromChildren,
|
||||||
|
matchRoutes,
|
||||||
}),
|
}),
|
||||||
|
Sentry.replayIntegration(),
|
||||||
],
|
],
|
||||||
release: version,
|
beforeBreadcrumb(breadcrumb) {
|
||||||
tracesSampleRate: 0.1,
|
|
||||||
beforeBreadcrumb(breadcrumb, hint?) {
|
|
||||||
if (breadcrumb.data && breadcrumb.data.url) {
|
if (breadcrumb.data && breadcrumb.data.url) {
|
||||||
const url = breadcrumb.data.url.replace(/token=.*/, '');
|
const url = breadcrumb.data.url.replace(/token=.*/, '');
|
||||||
breadcrumb.data.url = url;
|
breadcrumb.data.url = url;
|
||||||
}
|
}
|
||||||
return breadcrumb;
|
return breadcrumb;
|
||||||
},
|
},
|
||||||
|
tracesSampleRate: 0.1,
|
||||||
|
tracePropagationTargets: [/^(?!\/api\/(ws|static)).*$/],
|
||||||
|
replaysSessionSampleRate: 0.1,
|
||||||
|
replaysOnErrorSampleRate: 0.1,
|
||||||
|
release: version,
|
||||||
});
|
});
|
||||||
|
|
||||||
// monaco 编辑器配置cdn和locale
|
// monaco 编辑器配置cdn和locale
|
||||||
|
|
Loading…
Reference in New Issue
Block a user