Skip to content

Commit 477de7d

Browse files
committed
支持SDK请求监控
1 parent b0ea053 commit 477de7d

File tree

14 files changed

+185
-21
lines changed

14 files changed

+185
-21
lines changed

account.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ type AccountAddSchema struct {
3333

3434
// AccountAdd 添加客服账号
3535
func (r *Client) AccountAdd(options AccountAddOptions) (info AccountAddSchema, err error) {
36-
data, err := util.HttpPost(fmt.Sprintf(accountAddAddr, r.accessToken), options)
36+
target := fmt.Sprintf(accountAddAddr, r.accessToken)
37+
r.recordUpdate(target)
38+
39+
data, err := util.HttpPost(target, options)
3740
if err != nil {
3841
return info, err
3942
}
@@ -51,7 +54,10 @@ type AccountDelOptions struct {
5154

5255
// AccountDel 删除客服账号
5356
func (r *Client) AccountDel(options AccountDelOptions) (info BaseModel, err error) {
54-
data, err := util.HttpPost(fmt.Sprintf(accountDelAddr, r.accessToken), options)
57+
target := fmt.Sprintf(accountDelAddr, r.accessToken)
58+
r.recordUpdate(target)
59+
60+
data, err := util.HttpPost(target, options)
5561
if err != nil {
5662
return info, err
5763
}
@@ -71,7 +77,10 @@ type AccountUpdateOptions struct {
7177

7278
// AccountUpdate 修复客服账号
7379
func (r *Client) AccountUpdate(options AccountUpdateOptions) (info BaseModel, err error) {
74-
data, err := util.HttpPost(fmt.Sprintf(accountUpdateAddr, r.accessToken), options)
80+
target := fmt.Sprintf(accountUpdateAddr, r.accessToken)
81+
r.recordUpdate(target)
82+
83+
data, err := util.HttpPost(target, options)
7584
if err != nil {
7685
return info, err
7786
}
@@ -97,7 +106,10 @@ type AccountListSchema struct {
97106

98107
// AccountList 获取客服账号列表
99108
func (r *Client) AccountList() (info AccountListSchema, err error) {
100-
data, err := util.HttpGet(fmt.Sprintf(accountListAddr, r.accessToken))
109+
target := fmt.Sprintf(accountListAddr, r.accessToken)
110+
r.recordUpdate(target)
111+
112+
data, err := util.HttpGet(target)
101113
if err != nil {
102114
return info, err
103115
}
@@ -122,7 +134,10 @@ type AddContactWaySchema struct {
122134

123135
// AddContactWay 获取客服账号链接
124136
func (r *Client) AddContactWay(options AddContactWayOptions) (info AddContactWaySchema, err error) {
125-
data, err := util.HttpPost(fmt.Sprintf(addContactWayAddr, r.accessToken), options)
137+
target := fmt.Sprintf(addContactWayAddr, r.accessToken)
138+
r.recordUpdate(target)
139+
140+
data, err := util.HttpPost(target, options)
126141
if err != nil {
127142
return info, err
128143
}

cache/cache.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ import "time"
55
type Cache interface {
66
Set(k, v string, expires time.Duration) error
77
Get(k string) (string, error)
8+
Scan(cursor uint64, match string, count int64) (keys []string, newCursor uint64, err error)
89
}

cache/redis.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,8 @@ func (r *Redis) Get(k string) (string, error) {
122122
return "", err
123123
}
124124
return con, nil
125+
}
126+
127+
func (r *Redis) Scan(cursor uint64, match string, count int64) (keys []string, newCursor uint64, err error) {
128+
return r.Point.Scan(context.TODO(), cursor, match, count).Result()
125129
}

client.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type Options struct {
2121
Cache cache.Cache // 数据缓存
2222
ExpireTime time.Duration // 令牌过期时间
2323
IsCloseCache bool // 是否关闭自动缓存AccessToken, 默认缓存
24+
MonitorOpen bool // 是否开启监控
25+
MonitorLogExpireTime time.Duration // 监控日志过期时间,默认三天
2426
}
2527

2628
// Client 微信客服实例
@@ -35,6 +37,8 @@ type Client struct {
3537
mutex sync.Mutex
3638
accessToken string // 用户访问凭证
3739
isCloseCache bool // 是否自动缓存AccessToken, 默认缓存
40+
monitorOpen bool // 是否开启监控
41+
monitorLogExpireTime time.Duration // 监控日志过期时间,默认三天
3842
}
3943

4044
// New 初始化微信客服实例
@@ -44,7 +48,11 @@ func New(options Options) (client *Client, err error) {
4448
}
4549

4650
if options.ExpireTime == 0 {
47-
options.ExpireTime = 6000
51+
options.ExpireTime = 6000 * time.Second
52+
}
53+
54+
if options.MonitorOpen && options.MonitorLogExpireTime == 0 {
55+
options.MonitorLogExpireTime = 3 * 24 * 3600
4856
}
4957

5058
client = &Client{
@@ -57,6 +65,8 @@ func New(options Options) (client *Client, err error) {
5765
eventQueue: sync.Map{},
5866
mutex: sync.Mutex{},
5967
isCloseCache: options.IsCloseCache,
68+
monitorOpen: options.MonitorOpen,
69+
monitorLogExpireTime: options.MonitorLogExpireTime,
6070
}
6171

6272
if err = client.initAccessToken(); err != nil {

customer.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ type CustomerBatchGetSchema struct {
3333

3434
// CustomerBatchGet 客户基本信息获取
3535
func (r *Client) CustomerBatchGet(options CustomerBatchGetOptions) (info CustomerBatchGetSchema, err error) {
36-
data, err := util.HttpPost(fmt.Sprintf(customerBatchGetAddr, r.accessToken), options)
36+
target := fmt.Sprintf(customerBatchGetAddr, r.accessToken)
37+
r.recordUpdate(target)
38+
39+
data, err := util.HttpPost(target, options)
3740
if err != nil {
3841
return info, err
3942
}

media.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ func (r *Client) MediaUpload(options MediaUploadOptions) (info MediaUploadSchema
4747
FileSize: options.FileSize,
4848
File: options.File,
4949
}
50-
data, err := util.HttpPostFile(fmt.Sprintf(mediaUploadAddr, r.accessToken, options.Type), fileOptions)
50+
target := fmt.Sprintf(mediaUploadAddr, r.accessToken, options.Type)
51+
r.recordUpdate(target)
52+
53+
data, err := util.HttpPostFile(target, fileOptions)
5154
if err != nil {
5255
return info, err
5356
}
@@ -67,7 +70,10 @@ func (r *Client) MediaUpload(options MediaUploadOptions) (info MediaUploadSchema
6770
//视频(video) :10MB,支持MP4格式
6871
//普通文件(file):20MB
6972
func (r *Client) MediaOriginUpload(fileName, fileType string, size int, body []byte) (info MediaUploadSchema, err error) {
70-
data, err := util.HttpPostOriginFile(fmt.Sprintf(mediaUploadAddr, r.accessToken, fileType), fileName, size, body)
73+
target := fmt.Sprintf(mediaUploadAddr, r.accessToken, fileType)
74+
r.recordUpdate(target)
75+
76+
data, err := util.HttpPostOriginFile(target, fileName, size, body)
7177
if err != nil {
7278
return info, err
7379
}

monitor.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package WeChatCustomerServiceSDK
2+
3+
import (
4+
"github.com/NICEXAI/WeChatCustomerServiceSDK/util"
5+
"strconv"
6+
"strings"
7+
"time"
8+
)
9+
10+
// MonitorSchema SDK监控数据
11+
type MonitorSchema map[string]map[string]int
12+
13+
// Monitor 获取当前服务SDK调用统计数据
14+
func (r *Client) Monitor() MonitorSchema {
15+
keyList := make([]string, 0)
16+
cursor := uint64(0)
17+
hasMore := true
18+
19+
for hasMore {
20+
keys, newCursor, err := r.cache.Scan(cursor, "wechat:log:" + r.corpID + "*", 1000)
21+
if err != nil {
22+
break
23+
}
24+
if newCursor == 0 || len(keys) == 0 {
25+
hasMore = false
26+
}
27+
cursor = newCursor
28+
keyList = append(keyList, keys...)
29+
}
30+
31+
monitorInfo := MonitorSchema{}
32+
for _, key := range keyList {
33+
options := strings.Split(key, ":")
34+
if len(options) != 5 {
35+
continue
36+
}
37+
con, err := r.cache.Get(key)
38+
if err != nil {
39+
continue
40+
}
41+
timeDic := monitorInfo[options[3]]
42+
if timeDic == nil {
43+
monitorInfo[options[3]] = map[string]int{}
44+
}
45+
count, err := strconv.Atoi(con)
46+
if err != nil {
47+
continue
48+
}
49+
monitorInfo[options[3]][options[4]] = count
50+
}
51+
return monitorInfo
52+
}
53+
54+
//记录SDK调用信息
55+
func (r *Client) recordUpdate(path string) {
56+
if !r.monitorOpen {
57+
return
58+
}
59+
path = util.ParseRoute(path)
60+
if path == "" {
61+
return
62+
}
63+
recordKey := "wechat:log:" + r.corpID + ":" + time.Now().Format("2006010215") + ":" + path[1:]
64+
con, err := r.cache.Get(recordKey)
65+
if err != nil {
66+
return
67+
}
68+
if con == "" {
69+
if err = r.cache.Set(recordKey, strconv.Itoa(1), r.monitorLogExpireTime); err != nil {
70+
return
71+
}
72+
return
73+
}
74+
count, err := strconv.Atoi(con)
75+
if err != nil {
76+
return
77+
}
78+
_ = r.cache.Set(recordKey, strconv.Itoa(count + 1), r.monitorLogExpireTime)
79+
}

sendmsg.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ type SendMsgSchema struct {
1919

2020
// SendMsg 获取消息
2121
func (r *Client) SendMsg(options interface{}) (info SendMsgSchema, err error) {
22-
data, err := util.HttpPost(fmt.Sprintf(sendMsgAddr, r.accessToken), options)
22+
target := fmt.Sprintf(sendMsgAddr, r.accessToken)
23+
r.recordUpdate(target)
24+
25+
data, err := util.HttpPost(target, options)
2326
if err != nil {
2427
return info, err
2528
}

servicer.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ type ReceptionistSchema struct {
3232

3333
// ReceptionistAdd 添加接待人员
3434
func (r *Client) ReceptionistAdd(options ReceptionistOptions) (info ReceptionistSchema, err error) {
35-
data, err := util.HttpPost(fmt.Sprintf(receptionistAddAddr, r.accessToken), options)
35+
target := fmt.Sprintf(receptionistAddAddr, r.accessToken)
36+
r.recordUpdate(target)
37+
38+
data, err := util.HttpPost(target, options)
3639
if err != nil {
3740
return info, err
3841
}
@@ -45,7 +48,10 @@ func (r *Client) ReceptionistAdd(options ReceptionistOptions) (info Receptionist
4548

4649
// ReceptionistDel 删除接待人员
4750
func (r *Client) ReceptionistDel(options ReceptionistOptions) (info ReceptionistSchema, err error) {
48-
data, err := util.HttpPost(fmt.Sprintf(receptionistDelAddr, r.accessToken), options)
51+
target := fmt.Sprintf(receptionistDelAddr, r.accessToken)
52+
r.recordUpdate(target)
53+
54+
data, err := util.HttpPost(target, options)
4955
if err != nil {
5056
return info, err
5157
}
@@ -67,7 +73,10 @@ type ReceptionistListSchema struct {
6773

6874
// ReceptionistList 获取接待人员列表
6975
func (r *Client) ReceptionistList(kfID string) (info ReceptionistListSchema, err error) {
70-
data, err := util.HttpGet(fmt.Sprintf(receptionistListAddr, r.accessToken, kfID))
76+
target := fmt.Sprintf(receptionistListAddr, r.accessToken, kfID)
77+
r.recordUpdate(target)
78+
79+
data, err := util.HttpGet(target)
7180
if err != nil {
7281
return info, err
7382
}

servicestate.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ type ServiceStateGetSchema struct {
3333
//3 由人工接待 人工接待中。可选择结束会话
3434
//4 已结束 会话已经结束。不允许变更会话状态,等待用户重新发起咨询
3535
func (r *Client) ServiceStateGet(options ServiceStateGetOptions) (info ServiceStateGetSchema, err error) {
36-
data, err := util.HttpPost(fmt.Sprintf(serviceStateGetAddr, r.accessToken), options)
36+
target := fmt.Sprintf(serviceStateGetAddr, r.accessToken)
37+
r.recordUpdate(target)
38+
39+
data, err := util.HttpPost(target, options)
3740
if err != nil {
3841
return info, err
3942
}
@@ -54,7 +57,10 @@ type ServiceStateTransOptions struct {
5457

5558
// ServiceStateTrans 变更会话状态
5659
func (r *Client) ServiceStateTrans(options ServiceStateTransOptions) (info BaseModel, err error) {
57-
data, err := util.HttpPost(fmt.Sprintf(serviceStateTransAddr, r.accessToken), options)
60+
target := fmt.Sprintf(serviceStateTransAddr, r.accessToken)
61+
r.recordUpdate(target)
62+
63+
data, err := util.HttpPost(target, options)
5864
if err != nil {
5965
return info, err
6066
}

0 commit comments

Comments
 (0)