This commit is contained in:
parent
9dd5dcb9d2
commit
595e4c62f9
@ -21,7 +21,7 @@ env:
|
|||||||
SSH_PASSWORD: ${{ github.ref_name == 'main' && vars.SSH_PASSWORD || vars.DEV_SSH_PASSWORD }}
|
SSH_PASSWORD: ${{ github.ref_name == 'main' && vars.SSH_PASSWORD || vars.DEV_SSH_PASSWORD }}
|
||||||
# TG通知
|
# TG通知
|
||||||
TG_BOT_TOKEN: 8114337882:AAHkEx03HSu7RxN4IHBJJEnsK9aPPzNLIk0
|
TG_BOT_TOKEN: 8114337882:AAHkEx03HSu7RxN4IHBJJEnsK9aPPzNLIk0
|
||||||
TG_CHAT_ID: "-49402438031"
|
TG_CHAT_ID: "-4940243803"
|
||||||
# Go构建变量
|
# Go构建变量
|
||||||
SERVICE: vpn
|
SERVICE: vpn
|
||||||
SERVICE_STYLE: vpn
|
SERVICE_STYLE: vpn
|
||||||
|
|||||||
38
docker-compose.dev.yml
Normal file
38
docker-compose.dev.yml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: ppanel-mysql
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: ppanel_dev
|
||||||
|
MYSQL_DATABASE: ppanel
|
||||||
|
MYSQL_USER: ppanel
|
||||||
|
MYSQL_PASSWORD: ppanel_dev
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- ppanel_mysql_data:/var/lib/mysql
|
||||||
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pppanel_dev"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: ppanel-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- ppanel_redis_data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
ppanel_mysql_data:
|
||||||
|
ppanel_redis_data:
|
||||||
14
grafana/provisioning/dashboards/dashboards.yml
Normal file
14
grafana/provisioning/dashboards/dashboards.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
providers:
|
||||||
|
- name: PPanel
|
||||||
|
orgId: 1
|
||||||
|
folder: PPanel
|
||||||
|
folderUid: ppanel
|
||||||
|
type: file
|
||||||
|
disableDeletion: false
|
||||||
|
allowUiUpdates: true
|
||||||
|
updateIntervalSeconds: 30
|
||||||
|
options:
|
||||||
|
path: /etc/grafana/provisioning/dashboards/json
|
||||||
|
foldersFromFilesStructure: false
|
||||||
48
grafana/provisioning/datasources/datasources.yml
Normal file
48
grafana/provisioning/datasources/datasources.yml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
datasources:
|
||||||
|
- name: Prometheus
|
||||||
|
uid: prometheus
|
||||||
|
type: prometheus
|
||||||
|
access: proxy
|
||||||
|
url: http://prometheus:9090
|
||||||
|
isDefault: true
|
||||||
|
editable: true
|
||||||
|
jsonData:
|
||||||
|
httpMethod: POST
|
||||||
|
manageAlerts: true
|
||||||
|
prometheusType: Prometheus
|
||||||
|
prometheusVersion: 2.50.0
|
||||||
|
timeInterval: 15s
|
||||||
|
|
||||||
|
- name: Loki
|
||||||
|
uid: loki
|
||||||
|
type: loki
|
||||||
|
access: proxy
|
||||||
|
url: http://loki:3100
|
||||||
|
editable: true
|
||||||
|
jsonData:
|
||||||
|
derivedFields:
|
||||||
|
- datasourceUid: tempo
|
||||||
|
matcherRegex: '"(?:trace|traceID|trace_id)"\s*:\s*"([a-f0-9]{32})"'
|
||||||
|
name: TraceID
|
||||||
|
url: '$${__value.raw}'
|
||||||
|
|
||||||
|
- name: Tempo
|
||||||
|
uid: tempo
|
||||||
|
type: tempo
|
||||||
|
access: proxy
|
||||||
|
url: http://tempo:3200
|
||||||
|
editable: true
|
||||||
|
jsonData:
|
||||||
|
tracesToLogsV2:
|
||||||
|
datasourceUid: loki
|
||||||
|
filterByTraceID: true
|
||||||
|
filterBySpanID: false
|
||||||
|
tags:
|
||||||
|
- key: service.name
|
||||||
|
value: service_name
|
||||||
|
tracesToMetrics:
|
||||||
|
datasourceUid: prometheus
|
||||||
|
serviceMap:
|
||||||
|
datasourceUid: prometheus
|
||||||
@ -119,7 +119,12 @@ func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasi
|
|||||||
}
|
}
|
||||||
userInfo.Commission = req.Commission
|
userInfo.Commission = req.Commission
|
||||||
}
|
}
|
||||||
tool.DeepCopy(userInfo, req)
|
userInfo.Avatar = req.Avatar
|
||||||
|
userInfo.ReferCode = req.ReferCode
|
||||||
|
userInfo.RefererId = req.RefererId
|
||||||
|
userInfo.Enable = &req.Enable
|
||||||
|
userInfo.IsAdmin = &req.IsAdmin
|
||||||
|
userInfo.Remark = req.Remark
|
||||||
userInfo.OnlyFirstPurchase = &req.OnlyFirstPurchase
|
userInfo.OnlyFirstPurchase = &req.OnlyFirstPurchase
|
||||||
userInfo.ReferralPercentage = req.ReferralPercentage
|
userInfo.ReferralPercentage = req.ReferralPercentage
|
||||||
|
|
||||||
|
|||||||
169
log.txt
Normal file
169
log.txt
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
跳至主要内容
|
||||||
|
|
||||||
|
Grafana
|
||||||
|
探索
|
||||||
|
Loki
|
||||||
|
搜索...
|
||||||
|
⌘+k
|
||||||
|
|
||||||
|
|
||||||
|
User avatar
|
||||||
|
探索
|
||||||
|
|
||||||
|
轮廓
|
||||||
|
Loki logo
|
||||||
|
Loki
|
||||||
|
|
||||||
|
转到无查询
|
||||||
|
|
||||||
|
拆分
|
||||||
|
|
||||||
|
添加
|
||||||
|
|
||||||
|
|
||||||
|
过去 24 小时
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
运行查询
|
||||||
|
|
||||||
|
|
||||||
|
分享
|
||||||
|
|
||||||
|
|
||||||
|
直播
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A
|
||||||
|
(Loki)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Kick start your query
|
||||||
|
|
||||||
|
Label browser
|
||||||
|
Explain query
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{container="ppanel-server"} |= "10013" |= "user_subscribe"
|
||||||
|
|
||||||
|
Options
|
||||||
|
Type: Range
|
||||||
|
Line limit: 1000
|
||||||
|
Direction: Backward
|
||||||
|
This query will process approximately 20.3 GiB.
|
||||||
|
|
||||||
|
|
||||||
|
添加查询
|
||||||
|
|
||||||
|
查询历史记录
|
||||||
|
|
||||||
|
查询检查器
|
||||||
|
|
||||||
|
日志卷
|
||||||
|
info
|
||||||
|
Total: 717
|
||||||
|
Loki
|
||||||
|
日志
|
||||||
|
|
||||||
|
|
||||||
|
717 lines displayed
|
||||||
|
已处理的总字节数:
|
||||||
|
23.4 GB
|
||||||
|
Common labels:
|
||||||
|
container=ppanel-server
|
||||||
|
logstream=stdout
|
||||||
|
service_name=ppanel-server
|
||||||
|
已展开
|
||||||
|
|
||||||
|
滚动到底部
|
||||||
|
|
||||||
|
最新日志在前
|
||||||
|
|
||||||
|
搜索日志
|
||||||
|
|
||||||
|
去重
|
||||||
|
|
||||||
|
筛选级别
|
||||||
|
|
||||||
|
显示毫秒
|
||||||
|
ms
|
||||||
|
换行显示 JSON
|
||||||
|
+
|
||||||
|
Columns not supported
|
||||||
|
|
||||||
|
突出显示文本
|
||||||
|
|
||||||
|
大字体
|
||||||
|
|
||||||
|
下载日志
|
||||||
|
|
||||||
|
滚动到顶部
|
||||||
|
|
||||||
|
|
||||||
|
2026-04-30 08:33:29.296 info 303029-04-04 00:00:00.296 debug [GORM] SQL Executed duration=0.5ms caller=user/queryUserSubscribeLogic.go:47 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE `user_id` = 19764 AND `status` IN (0,1,2,3) AND (`expire_time` > '2026-04-30 23:33:29.295' OR `finished_at` >= '2026-04-23 23:33:29.295' OR `expire_time` = '1970-01-01 08:00:00') trace=428ceb5c1001366ab0dfddaa0fd0cf8a rows=1 span=a0c44ec4143a6a77
|
||||||
|
|
||||||
|
2026-04-30 06:38:24.260 info 303024-04-04 00:00:00.260 debug [GORM] SQL Executed duration=0.2ms caller=group/recalculateGroupLogic.go:58 sql=UPDATE `user_subscribe` SET `node_group_id`=0,`updated_at`='2026-04-30 21:38:24.26' WHERE id = 10013 rows=1
|
||||||
|
|
||||||
|
2026-04-30 06:38:24.259 info 303024-04-04 00:00:00.259 debug assigning user_subscribe_id=10013 (subscribe_id=1) to node_group_id=0 (total_options=0, selected_first) caller=group/recalculateGroupLogic.go:504
|
||||||
|
|
||||||
|
2026-04-30 06:38:24.121 info 303024-04-04 00:00:00.121 info [SubscriptionFlow] renewal order updated existing subscription caller=common/subscriptionTrace.go:28 effective_user_id=20003 payment_id=2 expire_time=2026-05-30 21:38:24.118494775 +0800 CST user_id=20003 quantity=30 flow=order_subscription stage=subscription_renewed order_no=202604302137198938303097982 is_new_order=false user_subscribe_id=10013 subscribe_order_id=17216 subscribe_uuid_tail=936f5490 payment_method=EPay subscribe_token_tail=3cb4c6b3 user_subscribe_plan_id=1 subscribe_status=1 iap_expire_at=0 trace_type=subscription_flow parent_order_id=7448 order_type=2 order_status=4 order_subscribe_id=1 app_account_token_tail=e04447ca order_id=17216 subscription_user_id=20003 subscribe_owner_user_id=20003
|
||||||
|
|
||||||
|
2026-04-30 06:38:24.120 info 303024-04-04 00:00:00.120 debug [GORM] SQL Executed duration=1.7ms caller=user/subscribe.go:17 sql=UPDATE `user_subscribe` SET `id`=10013,`user_id`=20003,`order_id`=17216,`subscribe_id`=1,`node_group_id`=0,`group_locked`=false,`start_time`='2026-04-23 19:06:40.003',`expire_time`='2026-05-30 21:38:24.118',`finished_at`=NULL,`traffic`=0,`download`=0,`upload`=0,`expired_download`=0,`expired_upload`=0,`token`='e622c7a270caf7fd816f9dd83cb4c6b3',`uuid`='aabd8eb1-2569-4a69-b59c-15cd936f5490',`status`=1,`note`='',`updated_at`='2026-04-30 21:38:24.119' WHERE id = 10013 rows=1
|
||||||
|
|
||||||
|
2026-04-30 06:38:24.118 info 303024-04-04 00:00:00.118 debug [GORM] SQL Executed duration=0.2ms caller=user/subscribe.go:161 sql=SELECT * FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1 rows=1
|
||||||
|
|
||||||
|
2026-04-30 06:37:25.952 info 303025-04-04 00:00:00.952 debug [GORM] SQL Executed duration=0.1ms caller=group/recalculateGroupLogic.go:58 sql=UPDATE `user_subscribe` SET `node_group_id`=0,`updated_at`='2026-04-30 21:37:25.952' WHERE id = 10013 rows=1
|
||||||
|
|
||||||
|
2026-04-30 06:37:19.898 info 303019-04-04 00:00:00.898 info HTTP Request duration=6.088471ms caller=middleware/loggerMiddleware.go:113 decrypted_request_body={"coupon":"","payment":2,"quantity":30,"user_subscribe_id":10013} response_body={"code":200,"data":{"data":"SxIHPdGQQbeAwx5UYMaRaouIke61GH+VRSl/iSr63r/GVLuXfd+ljlQLmukw9UE/Fdjc5oSWDq5ApVyEBR4bF79eBcuDz+cYjjmnJIn1sXt8hIPlwKlhc50TFwe8/x2RlpsHsLUYaOYOivMv/iuH/A==","time":"18ab25fb776f18b9"},"msg":"success"} ip=112.96.81.74 trace=60ff721319b3cf1b8f328dc05f01cb99 status=200 request=POST api.hifast.biz/v1/public/order/renewal query= user-agent=HiFast/1.0.6-26042218 (Android; HUAWEI PLA-AL10; 12) Flutter device_decrypt_status=success api_header= request_body={"data":"xdcFznl62TSP5AiItT+OKZWELzq3mR+cUZ2COAZ7ERslZT+M8mmEI65BfwevDWXA6l9TjMLr5sRkR4+omRV3fbH+PkLJ7kvIf9WPQ9ASaNg=","time":"2026-04-30T21:37:19.943917"} span=99fda96ceb7ba495
|
||||||
|
|
||||||
|
2026-04-30 06:37:19.898 info 303019-04-04 00:00:00.898 info [SubscriptionFlow] renewal order persisted caller=common/subscriptionTrace.go:28 trace_type=subscription_flow order_no=202604302137198938303097982 user_id=20003 payment_id=2 parent_order_id=7448 quantity=30 app_account_token_tail=e04447ca resolved_user_subscribe_id=10013 stage=order_created order_id=17216 order_type=2 order_status=1 subscription_user_id=20003 trace=60ff721319b3cf1b8f328dc05f01cb99 span=99fda96ceb7ba495 effective_user_id=20003 order_subscribe_id=1 requested_user_subscribe_id=10013 flow=order_subscription payment_method=EPay is_new_order=false subscribe_token_tail=3cb4c6b3
|
||||||
|
|
||||||
|
2026-04-30 06:37:19.894 info 303019-04-04 00:00:00.894 debug [GORM] SQL Executed duration=0.5ms caller=order/renewalLogic.go:81 rows=1 span=99fda96ceb7ba495 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1 trace=60ff721319b3cf1b8f328dc05f01cb99
|
||||||
|
|
||||||
|
2026-04-30 06:37:19.893 info 303019-04-04 00:00:00.893 info [SubscriptionFlow] renewal order creation started caller=common/subscriptionTrace.go:28 effective_user_id=20003 quantity=30 trace=60ff721319b3cf1b8f328dc05f01cb99 trace_type=subscription_flow flow=order_subscription stage=order_create_start order_kind=renewal user_id=20003 span=99fda96ceb7ba495 requested_user_subscribe_id=10013 payment_id=2 coupon=
|
||||||
|
|
||||||
|
2026-04-30 06:36:05.808 info 30305-04-04 00:00:00.808 info HTTP Request duration=7.877334ms caller=middleware/loggerMiddleware.go:113 query= device_decrypt_status=success response_body={"code":200,"data":{"data":"ELE22mv7foWM+iFzrylO+xbiTWWO7gH9qclIxJzT8TRqS1fJN32GiWq/gtNlGpVWwX4iZoNjI0uOA/5lV4YltAfw3bL7sz+CcARgVEZ4NGFRqOt7bVm1RssagYLopQdfoueQ0Z+j7zOFkBlzNW+r3Q==","time":"18ab25ea37520766"},"msg":"success"} user-agent=HiFast/1.0.6-26042218 (Android; HUAWEI PLA-AL10; 12) Flutter request_body={"data":"a4U8LH1zN4LFF+aBBLoUHzEZoxJ4C6EL1nlDNeKb4m2Xwi8H1hk05qxbkvj3xz6kKdecrhF2G0G6rAavhNlKDDZhaHH/J5elqjw6tsQGluk=","time":"2026-04-30T21:36:05.852132"} request=POST api.hifast.biz/v1/public/order/renewal ip=112.96.81.74 decrypted_request_body={"coupon":"","payment":2,"quantity":30,"user_subscribe_id":10013} trace=7e1b88eed63e7ffba4a6e6e2482d399d status=200 api_header= span=d6bd668124fcad80
|
||||||
|
|
||||||
|
2026-04-30 06:36:05.808 info 30305-04-04 00:00:00.808 info [SubscriptionFlow] renewal order persisted caller=common/subscriptionTrace.go:28 app_account_token_tail=237eb1b5 span=d6bd668124fcad80 flow=order_subscription order_id=17213 order_subscribe_id=1 parent_order_id=7448 requested_user_subscribe_id=10013 trace=7e1b88eed63e7ffba4a6e6e2482d399d user_id=20003 payment_id=2 payment_method=EPay resolved_user_subscribe_id=10013 stage=order_created order_no=202604302136058021461564356 order_status=1 quantity=30 is_new_order=false trace_type=subscription_flow order_type=2 subscription_user_id=20003 effective_user_id=20003 subscribe_token_tail=3cb4c6b3
|
||||||
|
|
||||||
|
2026-04-30 06:36:05.802 info 30305-04-04 00:00:00.802 debug [GORM] SQL Executed duration=0.7ms caller=order/renewalLogic.go:81 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1 rows=1 trace=7e1b88eed63e7ffba4a6e6e2482d399d span=d6bd668124fcad80
|
||||||
|
|
||||||
|
2026-04-30 06:36:05.802 info 30305-04-04 00:00:00.802 info [SubscriptionFlow] renewal order creation started caller=common/subscriptionTrace.go:28 flow=order_subscription requested_user_subscribe_id=10013 payment_id=2 coupon= span=d6bd668124fcad80 trace_type=subscription_flow order_kind=renewal trace=7e1b88eed63e7ffba4a6e6e2482d399d stage=order_create_start user_id=20003 effective_user_id=20003 quantity=30
|
||||||
|
|
||||||
|
2026-04-30 06:35:46.036 info 303046-04-04 00:00:00.036 debug [GORM] SQL Executed duration=0.1ms caller=group/recalculateGroupLogic.go:58 sql=UPDATE `user_subscribe` SET `node_group_id`=0,`updated_at`='2026-04-30 21:35:46.036' WHERE id = 10013 rows=1
|
||||||
|
|
||||||
|
2026-04-30 06:35:38.276 info 303038-04-04 00:00:00.276 info HTTP Request duration=7.276753ms caller=middleware/loggerMiddleware.go:113 request=POST api.hifast.biz/v1/public/order/renewal ip=112.96.81.74 user-agent=HiFast/1.0.6-26042218 (Android; HUAWEI PLA-AL10; 12) Flutter device_decrypt_status=success trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 status=200 query= request_body={"data":"6cuaVRmMX/CGHQ+y0jrwjKTUx404hlB7/z+qPYpK9toUHAVMBrhVBC/cnZmzffjaPuqlUrLx9lSOTHDxv3GGqXZxDah5N4AimVY0dFsx6Bc=","time":"2026-04-30T21:35:38.294140"} decrypted_request_body={"coupon":"","payment":2,"quantity":30,"user_subscribe_id":10013} response_body={"code":200,"data":{"data":"iQSMczPB07C+ruU52emoga1TtBShOiBZOtU8jW9XzmQiKe9DjWCxGY+fFTnJ6LrQCXAQqZWwBpQgABpFWpcJ+MbRr5jk4S3ahwXzeHXBiMcGlgAJRb0G3O+K7h7z+6t+uhGNjzCE2CYFMuii+0T3rg==","time":"18ab25e3ce44be91"},"msg":"success"} api_header=
|
||||||
|
|
||||||
|
2026-04-30 06:35:38.276 info 303038-04-04 00:00:00.276 info [SubscriptionFlow] renewal order persisted caller=common/subscriptionTrace.go:28 subscription_user_id=20003 order_subscribe_id=1 effective_user_id=20003 payment_id=2 parent_order_id=7448 subscribe_token_tail=3cb4c6b3 trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 flow=order_subscription payment_method=EPay quantity=30 is_new_order=false app_account_token_tail=6b5d9042 order_no=202604302135382700174133469 requested_user_subscribe_id=10013 resolved_user_subscribe_id=10013 trace_type=subscription_flow stage=order_created order_id=17211 order_type=2 order_status=1 user_id=20003
|
||||||
|
|
||||||
|
2026-04-30 06:35:38.270 info 303038-04-04 00:00:00.270 debug [GORM] SQL Executed duration=0.5ms caller=order/renewalLogic.go:81 rows=1 trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1
|
||||||
|
|
||||||
|
2026-04-30 06:35:38.270 info 303038-04-04 00:00:00.270 info [SubscriptionFlow] renewal order creation started caller=common/subscriptionTrace.go:28 flow=order_subscription effective_user_id=20003 coupon= trace_type=subscription_flow payment_id=2 user_id=20003 quantity=30 trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 stage=order_create_start order_kind=renewal requested_user_subscribe_id=10013
|
||||||
|
|
||||||
|
按名称搜索字段
|
||||||
|
|
||||||
|
Show log level
|
||||||
|
0
|
||||||
|
字段
|
||||||
|
|
||||||
|
__stream_shard__
|
||||||
|
25%
|
||||||
|
|
||||||
|
container
|
||||||
|
100%
|
||||||
|
|
||||||
|
level
|
||||||
|
100%
|
||||||
|
|
||||||
|
logstream
|
||||||
|
100%
|
||||||
|
|
||||||
|
service_name
|
||||||
|
100%
|
||||||
36
loki/loki-config.yaml
Normal file
36
loki/loki-config.yaml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
auth_enabled: false
|
||||||
|
|
||||||
|
server:
|
||||||
|
http_listen_port: 3100
|
||||||
|
grpc_listen_port: 9096
|
||||||
|
|
||||||
|
common:
|
||||||
|
path_prefix: /loki
|
||||||
|
replication_factor: 1
|
||||||
|
ring:
|
||||||
|
instance_addr: 127.0.0.1
|
||||||
|
kvstore:
|
||||||
|
store: inmemory
|
||||||
|
|
||||||
|
schema_config:
|
||||||
|
configs:
|
||||||
|
- from: 2024-01-01
|
||||||
|
store: tsdb
|
||||||
|
object_store: filesystem
|
||||||
|
schema: v13
|
||||||
|
index:
|
||||||
|
prefix: index_
|
||||||
|
period: 24h
|
||||||
|
|
||||||
|
storage_config:
|
||||||
|
filesystem:
|
||||||
|
directory: /loki/chunks
|
||||||
|
|
||||||
|
limits_config:
|
||||||
|
allow_structured_metadata: true
|
||||||
|
retention_period: 168h
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
working_directory: /loki/compactor
|
||||||
|
retention_enabled: true
|
||||||
|
delete_request_store: filesystem
|
||||||
47
loki/promtail-config.yaml
Normal file
47
loki/promtail-config.yaml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
server:
|
||||||
|
http_listen_port: 9080
|
||||||
|
grpc_listen_port: 0
|
||||||
|
|
||||||
|
positions:
|
||||||
|
filename: /tmp/positions.yaml
|
||||||
|
|
||||||
|
clients:
|
||||||
|
- url: http://loki:3100/loki/api/v1/push
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: ppanel-file
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- localhost
|
||||||
|
labels:
|
||||||
|
job: ppanel-server
|
||||||
|
service_name: ppanel
|
||||||
|
__path__: /var/log/ppanel-server/*.log
|
||||||
|
|
||||||
|
- job_name: nginx-file
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- localhost
|
||||||
|
labels:
|
||||||
|
job: nginx
|
||||||
|
service_name: nginx
|
||||||
|
__path__: /var/log/nginx/*.log
|
||||||
|
|
||||||
|
- job_name: docker-containers
|
||||||
|
docker_sd_configs:
|
||||||
|
- host: unix:///var/run/docker.sock
|
||||||
|
refresh_interval: 15s
|
||||||
|
relabel_configs:
|
||||||
|
- source_labels: [__meta_docker_container_name]
|
||||||
|
regex: '/(.*)'
|
||||||
|
target_label: container
|
||||||
|
- source_labels: [__meta_docker_container_label_com_docker_compose_service]
|
||||||
|
target_label: compose_service
|
||||||
|
- source_labels: [__meta_docker_container_log_stream]
|
||||||
|
target_label: stream
|
||||||
|
- source_labels: [__meta_docker_container_name]
|
||||||
|
regex: '/(.*)'
|
||||||
|
target_label: service_name
|
||||||
|
- source_labels: [__meta_docker_container_id]
|
||||||
|
target_label: __path__
|
||||||
|
replacement: /var/lib/docker/containers/$1/$1-json.log
|
||||||
50
prometheus/prometheus.yml
Normal file
50
prometheus/prometheus.yml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
evaluation_interval: 15s
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: prometheus
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- prometheus:9090
|
||||||
|
|
||||||
|
- job_name: grafana
|
||||||
|
metrics_path: /metrics
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- grafana:3000
|
||||||
|
|
||||||
|
- job_name: node-exporter
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- node-exporter:9100
|
||||||
|
|
||||||
|
- job_name: cadvisor
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- cadvisor:8080
|
||||||
|
|
||||||
|
- job_name: redis-exporter
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- redis-exporter:9121
|
||||||
|
|
||||||
|
- job_name: mysql-exporter
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- mysql-exporter:9104
|
||||||
|
|
||||||
|
- job_name: nginx-exporter
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- nginx-exporter:9113
|
||||||
|
|
||||||
|
- job_name: loki
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- loki:3100
|
||||||
|
|
||||||
|
- job_name: tempo
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- tempo:3200
|
||||||
37
tempo/tempo-config.yaml
Normal file
37
tempo/tempo-config.yaml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
server:
|
||||||
|
http_listen_port: 3200
|
||||||
|
grpc_listen_port: 9095
|
||||||
|
|
||||||
|
distributor:
|
||||||
|
receivers:
|
||||||
|
otlp:
|
||||||
|
protocols:
|
||||||
|
grpc:
|
||||||
|
endpoint: 0.0.0.0:4317
|
||||||
|
http:
|
||||||
|
endpoint: 0.0.0.0:4318
|
||||||
|
|
||||||
|
ingester:
|
||||||
|
max_block_duration: 5m
|
||||||
|
|
||||||
|
compactor:
|
||||||
|
compaction:
|
||||||
|
block_retention: 168h
|
||||||
|
|
||||||
|
storage:
|
||||||
|
trace:
|
||||||
|
backend: local
|
||||||
|
wal:
|
||||||
|
path: /var/tempo/wal
|
||||||
|
local:
|
||||||
|
path: /var/tempo/blocks
|
||||||
|
|
||||||
|
metrics_generator:
|
||||||
|
registry:
|
||||||
|
external_labels:
|
||||||
|
source: tempo
|
||||||
|
cluster: ppanel
|
||||||
|
storage:
|
||||||
|
path: /var/tempo/generator/wal
|
||||||
|
remote_write:
|
||||||
|
- url: http://prometheus:9090/api/v1/write
|
||||||
136
tests/config.go
Normal file
136
tests/config.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// Package tests provides HTTP client helpers for manually testing ppanel-server APIs.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// go test -v -run TestXxx ./tests/
|
||||||
|
//
|
||||||
|
// Configure the constants below to match your local environment.
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ─── Environment Configuration ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const (
|
||||||
|
// BaseURL is the ppanel-server base URL (no trailing slash).
|
||||||
|
BaseURL = "http://localhost:8080"
|
||||||
|
|
||||||
|
// AdminToken is the JWT token for an admin user.
|
||||||
|
// Obtain by calling CallAdminLogin first, then paste the token here.
|
||||||
|
AdminToken = "YOUR_ADMIN_TOKEN"
|
||||||
|
|
||||||
|
// UserToken is the JWT token for a regular user.
|
||||||
|
// Obtain by calling CallUserLogin first, then paste the token here.
|
||||||
|
UserToken = "YOUR_USER_TOKEN"
|
||||||
|
|
||||||
|
// TestEmail is the email address for user-related test calls.
|
||||||
|
TestEmail = "test@example.com"
|
||||||
|
|
||||||
|
// TestPassword is the password for test user login.
|
||||||
|
TestPassword = "Test@123456"
|
||||||
|
|
||||||
|
// AdminEmail is the email for admin login.
|
||||||
|
AdminEmail = "admin@example.com"
|
||||||
|
|
||||||
|
// AdminPassword is the admin password.
|
||||||
|
AdminPassword = "Admin@123456"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ─── Request Options ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
type reqOption func(*http.Request)
|
||||||
|
|
||||||
|
// withToken adds a Bearer token to the request.
|
||||||
|
func withToken(token string) reqOption {
|
||||||
|
return func(r *http.Request) {
|
||||||
|
r.Header.Set("Authorization", "Bearer "+token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// withAdminToken adds the AdminToken.
|
||||||
|
func withAdminToken() reqOption { return withToken(AdminToken) }
|
||||||
|
|
||||||
|
// withUserToken adds the UserToken.
|
||||||
|
func withUserToken() reqOption { return withToken(UserToken) }
|
||||||
|
|
||||||
|
// ─── Core HTTP Helper ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
// doRequest sends an HTTP request and prints the response.
|
||||||
|
// body may be nil (for GET/DELETE without body), a map[string]any, or any JSON-serialisable value.
|
||||||
|
// Returns the raw response body as a string.
|
||||||
|
func doRequest(t *testing.T, method, path string, body any, opts ...reqOption) string {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
var reqBody io.Reader
|
||||||
|
if body != nil {
|
||||||
|
b, err := json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("marshal body: %v", err)
|
||||||
|
}
|
||||||
|
reqBody = bytes.NewReader(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(method, BaseURL+path, reqBody)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("new request: %v", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Accept", "application/json")
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("do request: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
raw, _ := io.ReadAll(resp.Body)
|
||||||
|
result := prettyJSON(raw)
|
||||||
|
t.Logf("[%s %s] %d\n%s", method, path, resp.StatusCode, result)
|
||||||
|
return string(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// doRequestRaw is like doRequest but for non-testing contexts (prints to stdout).
|
||||||
|
func doRequestRaw(method, path string, body any, opts ...reqOption) string {
|
||||||
|
var reqBody io.Reader
|
||||||
|
if body != nil {
|
||||||
|
b, _ := json.Marshal(body)
|
||||||
|
reqBody = bytes.NewReader(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := http.NewRequest(method, BaseURL+path, reqBody)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Accept", "application/json")
|
||||||
|
for _, o := range opts {
|
||||||
|
o(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("request error: %v\n", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
raw, _ := io.ReadAll(resp.Body)
|
||||||
|
result := prettyJSON(raw)
|
||||||
|
fmt.Printf("[%s %s] %d\n%s\n", method, path, resp.StatusCode, result)
|
||||||
|
return string(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func prettyJSON(raw []byte) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := json.Indent(&buf, raw, "", " "); err != nil {
|
||||||
|
return string(raw)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user