Skip to content

Commit fa4a78e

Browse files
committed
feat: support monitor
1 parent 5dfb396 commit fa4a78e

File tree

8 files changed

+214
-4
lines changed

8 files changed

+214
-4
lines changed

__tests__/monitor.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Monitor } from '../src';
2+
3+
describe('Monitor', () => {
4+
const credentials = {
5+
SecretId: process.env.TENCENT_SECRET_ID,
6+
SecretKey: process.env.TENCENT_SECRET_KEY,
7+
};
8+
const monitor = new Monitor(credentials, process.env.REGION);
9+
10+
test('get monitor data', async () => {
11+
const res = await monitor.get({
12+
functionName: 'serverless-unit-test',
13+
metric: 'Invocation',
14+
});
15+
16+
expect(res).toEqual({
17+
StartTime: expect.any(String),
18+
EndTime: expect.any(String),
19+
Period: 60,
20+
MetricName: 'Invocation',
21+
DataPoints: [
22+
{
23+
Dimensions: [
24+
{ Name: 'functionName', Value: 'serverless-unit-test' },
25+
{ Name: 'namespace', Value: 'default' },
26+
],
27+
Timestamps: expect.any(Array),
28+
Values: expect.any(Array),
29+
},
30+
],
31+
RequestId: expect.any(String),
32+
});
33+
});
34+
35+
test('[inverval] get monitor data', async () => {
36+
const res = await monitor.get({
37+
functionName: 'serverless-unit-test',
38+
metric: 'Invocation',
39+
interval: 3600,
40+
});
41+
42+
expect(res).toEqual({
43+
StartTime: expect.any(String),
44+
EndTime: expect.any(String),
45+
Period: 60,
46+
MetricName: 'Invocation',
47+
DataPoints: [
48+
{
49+
Dimensions: [
50+
{ Name: 'functionName', Value: 'serverless-unit-test' },
51+
{ Name: 'namespace', Value: 'default' },
52+
],
53+
Timestamps: expect.any(Array),
54+
Values: expect.any(Array),
55+
},
56+
],
57+
RequestId: expect.any(String),
58+
});
59+
});
60+
test('[period] get monitor data', async () => {
61+
const res = await monitor.get({
62+
functionName: 'serverless-unit-test',
63+
metric: 'Invocation',
64+
period: 300,
65+
});
66+
67+
expect(res).toEqual({
68+
StartTime: expect.any(String),
69+
EndTime: expect.any(String),
70+
Period: 300,
71+
MetricName: 'Invocation',
72+
DataPoints: [
73+
{
74+
Dimensions: [
75+
{ Name: 'functionName', Value: 'serverless-unit-test' },
76+
{ Name: 'namespace', Value: 'default' },
77+
],
78+
Timestamps: expect.any(Array),
79+
Values: expect.any(Array),
80+
},
81+
],
82+
RequestId: expect.any(String),
83+
});
84+
});
85+
});

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ export { default as Cfs } from './modules/cfs';
1414
export { default as Cynosdb } from './modules/cynosdb';
1515
export { default as Cls } from './modules/cls';
1616
export { default as Clb } from './modules/clb';
17+
export { default as Monitor } from './modules/monitor';

src/modules/interface.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ export enum ApiServiceType {
1919
cynosdb = 'cynosdb',
2020
/** Postgres 数据库 (Postgres) */
2121
postgres = 'postgres',
22-
/** (VPC) */
22+
/** 私有网络 (VPC) */
2323
vpc = 'vpc',
24-
/** */
24+
/* 访问管理 (CAM) */
2525
cam = 'cam',
2626

27+
// 负载均衡 (CLB)*/
2728
clb = 'clb',
29+
30+
// 监控 */
31+
monitor = 'monitor',
2832
}
2933

3034
export type RegionType = string;

src/modules/monitor/apis.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { ApiFactory } from '../../utils/api';
2+
import { ApiServiceType } from '../interface';
3+
4+
const ACTIONS = ['GetMonitorData'] as const;
5+
6+
export type ActionType = typeof ACTIONS[number];
7+
8+
const APIS = ApiFactory({
9+
debug: false,
10+
isV3: true,
11+
serviceType: ApiServiceType.monitor,
12+
version: '2018-07-24',
13+
actions: ACTIONS,
14+
});
15+
16+
export default APIS;

src/modules/monitor/constants.ts

Whitespace-only changes.

src/modules/monitor/index.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Capi } from '@tencent-sdk/capi';
2+
// import { waitResponse } from '@ygkit/request';
3+
// import { ApiError } from '../../utils/error';
4+
import { ApiServiceType } from '../interface';
5+
import { GetMonitorDataInputs } from './interface';
6+
import APIS, { ActionType } from './apis';
7+
import { pascalCaseProps } from '../../utils/index';
8+
import { dtz, formatDate } from '../../utils/dayjs';
9+
import { CapiCredentials, RegionType } from '../interface';
10+
11+
export default class Monitor {
12+
credentials: CapiCredentials;
13+
capi: Capi;
14+
region: RegionType;
15+
16+
constructor(credentials: CapiCredentials, region: RegionType = 'ap-guangzhou') {
17+
this.credentials = credentials;
18+
this.region = region;
19+
20+
this.capi = new Capi({
21+
Region: region,
22+
ServiceType: ApiServiceType.monitor,
23+
SecretId: this.credentials.SecretId!,
24+
SecretKey: this.credentials.SecretKey!,
25+
Token: this.credentials.Token,
26+
});
27+
}
28+
29+
async get(inputs: GetMonitorDataInputs) {
30+
const {
31+
metric,
32+
functionName,
33+
namespace = 'default',
34+
alias,
35+
period = 60,
36+
interval = 900,
37+
startTime,
38+
endTime = Date.now(),
39+
} = inputs;
40+
41+
const endDate = dtz(endTime);
42+
const startDate = startTime ? dtz(startTime) : endDate.add(0 - interval, 'second');
43+
const formatedStartTime = formatDate(startDate, true);
44+
const formatedEndTime = formatDate(endDate, true);
45+
46+
const dimensions = [
47+
{
48+
Name: 'namespace',
49+
Value: namespace,
50+
},
51+
{
52+
Name: 'functionName',
53+
Value: functionName,
54+
},
55+
];
56+
57+
if (alias) {
58+
dimensions.push({
59+
Name: 'alias',
60+
Value: alias,
61+
});
62+
}
63+
64+
const res = await this.request({
65+
MetricName: metric,
66+
Action: 'GetMonitorData',
67+
Namespace: 'QCE/SCF_V2',
68+
Instances: [
69+
{
70+
Dimensions: dimensions,
71+
},
72+
],
73+
Period: period,
74+
StartTime: formatedStartTime,
75+
EndTime: formatedEndTime,
76+
});
77+
78+
return res;
79+
}
80+
81+
async request({ Action, ...data }: { Action: ActionType; [key: string]: any }) {
82+
const result = await APIS[Action](this.capi, pascalCaseProps(data));
83+
return result;
84+
}
85+
}

src/modules/monitor/interface.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export interface GetMonitorDataInputs {
2+
// 指标名称,参考云函数监控指标文档:https://cloud.tencent.com/document/product/248/45130
3+
metric: string;
4+
// 函数名称
5+
functionName: string;
6+
// 命名空间
7+
namespace?: string;
8+
// 别名,默认流量,$LATEST
9+
alias?: string;
10+
// 时间间隔,单位秒,默认为 900s
11+
interval?: number;
12+
// 统计周期,单位秒,默认为 60s
13+
period?: number;
14+
// 开始时间, 格式:2018-09-22T19:51:23+08:00
15+
startTime?: string;
16+
// 结束时间, 格式:2018-09-22T19:51:23+08:00
17+
endTime?: string;
18+
}

src/utils/dayjs.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ const dtz = (date: ConfigType = Date.now()) => {
1212
};
1313

1414
const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
15+
const TIME_FORMAT_TIMEZONE = 'YYYY-MM-DDTHH:mm:ssZ';
1516

16-
function formatDate(date: ConfigType): string {
17-
return dtz(date).format(TIME_FORMAT);
17+
function formatDate(date: ConfigType, withTimeout = false): string {
18+
return dtz(date).format(withTimeout ? TIME_FORMAT_TIMEZONE : TIME_FORMAT);
1819
}
1920

2021
export { dayjs, dtz, Dayjs, TIME_FORMAT, formatDate };

0 commit comments

Comments
 (0)