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 }}
|
||||
# TG通知
|
||||
TG_BOT_TOKEN: 8114337882:AAHkEx03HSu7RxN4IHBJJEnsK9aPPzNLIk0
|
||||
TG_CHAT_ID: "-49402438031"
|
||||
TG_CHAT_ID: "-4940243803"
|
||||
# Go构建变量
|
||||
SERVICE: 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
|
||||
}
|
||||
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.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