Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@edgeone/ef-cls-sdk

Package Overview
Dependencies
Maintainers
2
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@edgeone/ef-cls-sdk - npm Package Compare versions

Comparing version
1.0.0
to
1.0.1
+1
dist/example/src/test.d.ts
export {};
import { AsyncClient, Content, LogGroup, LogItem, PutLogsRequest } from '../../src';
const TENCENT_SECRET_ID = 'xxxxx';
const TENCENT_SECRET_KEY = 'xxxxx';
const CLS_END_POINT = 'ap-xxxxx.cls.tencentcs.com';
const CLS_TOPIC_ID = 'xxxxx';
const clsAsyncClient = new AsyncClient({
endpoint: CLS_END_POINT,
secretId: TENCENT_SECRET_ID,
secretKey: TENCENT_SECRET_KEY,
sourceIp: 'edge',
retry_times: 1,
});
async function clsUpload(data) {
const logGroup = new LogGroup();
const logItem = new LogItem();
const logTime = Math.floor(Date.now() / 1000);
const logContent = new Content('__CONTENT__', JSON.stringify(data));
logItem.setTime(logTime);
logItem.pushBack(logContent);
logGroup.addLogs(logItem);
const clsRequest = new PutLogsRequest(CLS_TOPIC_ID, logGroup);
return await clsAsyncClient.PutLogs(clsRequest);
}
async function doClsUpload(request) {
try {
const data = await request.clone().text();
await clsUpload(data);
}
catch (err) {
console.error(`cls upload error: ${err}`);
}
}
async function handleRequest(event) {
const { request } = event;
const contentType = request.headers.get('content-type') || '';
if (contentType.includes('application/json') || contentType.includes('text/plain')) {
event.waitUntil(doClsUpload(request));
}
return;
}
addEventListener('fetch', handleRequest);
import { AsyncClientOptions } from './models';
import { PutLogsRequest } from './request/putLogsRequest';
import { SearchLogRequest } from './request/searchResquest';
export declare class AsyncClient {
private httpType;
private hostName;
private secretId;
private secretKey;
private sourceIp;
private retry_times;
constructor(options: AsyncClientOptions);
PutLogs(request: PutLogsRequest): Promise<any>;
SearchLog(request: SearchLogRequest): Promise<any>;
private sendLogs;
private getCommonHeadPara;
}
import TencentCloudClsSDKException from './exception';
import { CONST_CONTENT_LENGTH, CONST_CONTENT_TYPE, CONST_HOST, CONST_JSON, CONST_PROTO_BUF, CONST_MAX_PUT_SIZE, TOPIC_ID, SORT, CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, CONST_AUTHORIZATION, TOPIC_IDS, START_TIME, END_TIME, LOGSET_ID, LIMIT, CONTEXT, CONST_HTTP_METHOD_GET, QUERY_STRING, } from './common/constants';
import { signature } from './common/sign';
import { Response } from './response/response';
export class AsyncClient {
constructor(options) {
if (options == null || options == undefined) {
throw new TencentCloudClsSDKException('AsyncClientOptions invalid');
}
if (options.endpoint == null || options.endpoint == undefined || options.endpoint.length == 0) {
throw new TencentCloudClsSDKException('options endpoint can not be empty');
}
if (options.secretId == null || options.secretId == undefined || options.secretId.length == 0) {
throw new TencentCloudClsSDKException('options secretId can not be empty');
}
if (options.secretKey == null || options.secretKey == undefined || options.secretKey.length == 0) {
throw new TencentCloudClsSDKException('options secretKey can not be empty');
}
if (options.sourceIp == null || options.sourceIp == undefined || options.sourceIp.length == 0) {
throw new TencentCloudClsSDKException('options sourceIp can not be empty');
}
this.retry_times = options.retry_times;
if (options.retry_times == 0 || options.retry_times == undefined || options.retry_times == null) {
this.retry_times = 5;
}
if (options.endpoint.startsWith('http://')) {
this.hostName = options.endpoint.substring(7);
this.httpType = 'http://';
}
else if (options.endpoint.startsWith('https://')) {
this.hostName = options.endpoint.substring(8);
this.httpType = 'https://';
}
else {
this.hostName = options.endpoint;
this.httpType = 'http://';
}
while (this.hostName.endsWith('/')) {
this.hostName = this.hostName.substring(0, this.hostName.length - 1);
}
if (options.compress) {
}
this.secretId = options.secretId;
this.secretKey = options.secretKey;
this.sourceIp = options.sourceIp;
}
async PutLogs(request) {
const logBytes = request.getLogGroupBytes(this.sourceIp);
if (logBytes.length > CONST_MAX_PUT_SIZE) {
throw new TencentCloudClsSDKException(`InvalidLogSize. logItems' size exceeds maximum limitation : ${CONST_MAX_PUT_SIZE} bytes, logBytes=${logBytes.length}, topic=${request.getTopic()}`);
}
const headParameter = this.getCommonHeadPara(CONST_PROTO_BUF);
request.setParam(TOPIC_ID, request.getTopic());
const urlParameter = request.getAllParams();
for (let retryTimes = 0; retryTimes < this.retry_times; retryTimes++) {
try {
const res = await this.sendLogs(CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, urlParameter, headParameter, logBytes, request.getTopic());
const putLogRequest = new Response();
putLogRequest.setAllHeaders(res.headers);
putLogRequest.setHttpStatusCode(res.status);
if (putLogRequest.getHttpStatusCode() == 200) {
return putLogRequest;
}
if (retryTimes + 1 >= this.retry_times) {
throw new TencentCloudClsSDKException('send log failed and exceed retry times');
}
}
catch (error) {
if (error.response && error.response.status == 413) {
const putLogRequest = new Response();
putLogRequest.setAllHeaders(error.response.headers);
putLogRequest.setHttpStatusCode(error.response.status);
return putLogRequest;
}
if (retryTimes + 1 >= this.retry_times) {
const putLogRequest = new Response();
if (error.response) {
putLogRequest.setAllHeaders(error.response.headers);
putLogRequest.setHttpStatusCode(error.response.status);
}
throw new TencentCloudClsSDKException(`send log failed and exceed retry times. error: ${error.message}. request: ${JSON.stringify(putLogRequest)}`);
}
}
}
}
async SearchLog(request) {
if (request.LogsetId == null || request.LogsetId == undefined || request.LogsetId.length == 0) {
throw new TencentCloudClsSDKException('logset_id can not be empty');
}
if (request.TopicId == null || request.TopicId == undefined || request.TopicId.length == 0) {
throw new TencentCloudClsSDKException('topic_id can not be empty');
}
if (request.StartTime == null || request.StartTime == undefined || request.StartTime.length == 0) {
throw new TencentCloudClsSDKException('start_time can not be empty');
}
if (request.EndTime == null || request.EndTime == undefined || request.EndTime.length == 0) {
throw new TencentCloudClsSDKException('end_time can not be empty');
}
if (request.Limit == null ||
request.Limit == undefined ||
request.Limit.length == 0 ||
parseInt(request.Limit, 10) > 100) {
throw new TencentCloudClsSDKException('sort parameter is invalid');
}
if (request.Sort != 'asc' && request.Sort != 'desc') {
throw new TencentCloudClsSDKException('sort parameter is invalid');
}
const urlParameter = request.getAllParams();
urlParameter.set(TOPIC_IDS, request.TopicId);
urlParameter.set(LOGSET_ID, request.LogsetId);
urlParameter.set(START_TIME, request.StartTime);
urlParameter.set(END_TIME, request.EndTime);
urlParameter.set(LIMIT, request.Limit);
urlParameter.set(QUERY_STRING, request.QueryString);
if (request.Context != null && request.Context != undefined && request.Context.length > 0) {
urlParameter.set(CONTEXT, request.Context);
}
urlParameter.set(SORT, request.Sort);
const headParameter = this.getCommonHeadPara(CONST_JSON);
headParameter.delete(CONST_CONTENT_LENGTH);
const signature_str = await signature(this.secretId, this.secretKey, CONST_HTTP_METHOD_GET, '/searchlog', new Map(), headParameter, 300000);
headParameter.set(CONST_AUTHORIZATION, signature_str);
const headers = {};
headParameter.forEach((value, key) => {
headers[key] = value;
});
let uri = '';
urlParameter.forEach((value, key) => {
uri += `${key}=${encodeURIComponent(value)}&`;
});
uri = uri.substring(0, uri.length - 1);
return fetch(`${this.httpType + this.hostName}/searchlog` + `?${uri}`, {
method: 'GET',
headers,
});
}
async sendLogs(method, resourceUri, urlParameter, headParameter, body, topic) {
headParameter.set(CONST_CONTENT_LENGTH, body.length.toString());
const signature_str = await signature(this.secretId, this.secretKey, method, resourceUri, urlParameter, headParameter, 300000);
headParameter.set(CONST_AUTHORIZATION, signature_str);
const headers = {};
headParameter.forEach((value, key) => {
headers[key] = value;
});
return fetch(`${this.httpType + this.hostName + resourceUri}?${TOPIC_ID}=${topic}`, {
method: 'POST',
body,
headers,
});
}
getCommonHeadPara(contentType) {
const headParameter = new Map();
headParameter.set(CONST_CONTENT_LENGTH, '0');
headParameter.set(CONST_CONTENT_TYPE, contentType);
headParameter.set(CONST_HOST, this.hostName);
return headParameter;
}
}
export declare const CONST_CONTENT_TYPE = "Content-Type";
export declare const CONST_PROTO_BUF = "application/x-protobuf";
export declare const CONST_JSON = "application/json";
export declare const CONST_CONTENT_LENGTH = "Content-Length";
export declare const CONST_AUTHORIZATION = "Authorization";
export declare const CONST_GZIP_ENCODING = "deflate";
export declare const CONST_HTTP_METHOD_POST = "POST";
export declare const CONST_HTTP_METHOD_GET = "GET";
export declare const CONST_X_SLS_REQUESTID = "x-log-requestid";
export declare const CONST_HOST = "Host";
export declare const CONST_MD5 = "MD5";
export declare const UTF_8_ENCODING = "UTF-8";
export declare const CONST_LOCAL_IP = "127.0.0.1";
export declare const HTTP_CONNECT_TIME_OUT: number;
export declare const HTTP_SEND_TIME_OUT: number;
export declare const TOPIC_ID = "topic_id";
export declare const UPLOAD_LOG_RESOURCE_URI = "/structuredlog";
export declare const CONST_MAX_PUT_SIZE: number;
export declare const CONST_X_SLS_COMPRESSTYPE = "x-cls-compress-type";
export declare const CONST_LZ4 = "lz4";
export declare const TOPIC_IDS = "topic_ids";
export declare const LOGSET_ID = "logset_id";
export declare const START_TIME = "start_time";
export declare const END_TIME = "end_time";
export declare const QUERY_STRING = "query_string";
export declare const LIMIT = "limit";
export declare const CONTEXT = "context";
export declare const SORT = "sort";
export const CONST_CONTENT_TYPE = 'Content-Type';
export const CONST_PROTO_BUF = 'application/x-protobuf';
export const CONST_JSON = 'application/json';
export const CONST_CONTENT_LENGTH = 'Content-Length';
export const CONST_AUTHORIZATION = 'Authorization';
export const CONST_GZIP_ENCODING = 'deflate';
export const CONST_HTTP_METHOD_POST = 'POST';
export const CONST_HTTP_METHOD_GET = 'GET';
export const CONST_X_SLS_REQUESTID = 'x-log-requestid';
export const CONST_HOST = 'Host';
export const CONST_MD5 = 'MD5';
export const UTF_8_ENCODING = 'UTF-8';
export const CONST_LOCAL_IP = '127.0.0.1';
export const HTTP_CONNECT_TIME_OUT = 60 * 1000;
export const HTTP_SEND_TIME_OUT = 60 * 1000;
export const TOPIC_ID = 'topic_id';
export const UPLOAD_LOG_RESOURCE_URI = '/structuredlog';
export const CONST_MAX_PUT_SIZE = 1 * 1024 * 1024;
export const CONST_X_SLS_COMPRESSTYPE = 'x-cls-compress-type';
export const CONST_LZ4 = 'lz4';
export const TOPIC_IDS = 'topic_ids';
export const LOGSET_ID = 'logset_id';
export const START_TIME = 'start_time';
export const END_TIME = 'end_time';
export const QUERY_STRING = 'query_string';
export const LIMIT = 'limit';
export const CONTEXT = 'context';
export const SORT = 'sort';
import { cls } from '../../vendor/compiled';
export declare class LogGroup {
mLogs: cls.LogGroup;
constructor();
getFilename(): string;
setFilename(filename: string): void;
getSource(): string;
setSource(source: string): void;
addLogs(log: LogItem): void;
encode(): Uint8Array;
decode(buffer: Uint8Array): {
[key: string]: any;
};
verify(buffer: Uint8Array): string | null;
}
export declare class LogItem {
mContents: cls.Log;
constructor();
pushBack(content: Content): void;
setTime(time: number): void;
getLog(): cls.Log;
}
export declare class Content {
content: cls.Log.Content;
constructor(key: string, value: string);
getContent(): cls.Log.Content;
}
import { cls } from '../../vendor/compiled';
export class LogGroup {
constructor() {
this.mLogs = new cls.LogGroup();
}
getFilename() {
return this.mLogs.filename || '';
}
setFilename(filename) {
this.mLogs.filename = filename;
}
getSource() {
return this.mLogs.source || '';
}
setSource(source) {
this.mLogs.source = source;
}
addLogs(log) {
this.mLogs.logs.push(log.getLog());
}
encode() {
const list = new cls.LogGroupList();
list.logGroupList.push(this.mLogs);
return cls.LogGroupList.encode(list).finish();
}
decode(buffer) {
return cls.LogGroupList.decode(buffer).toJSON();
}
verify(buffer) {
return cls.LogGroupList.verify(buffer);
}
}
export class LogItem {
constructor() {
this.mContents = new cls.Log();
}
pushBack(content) {
this.mContents.contents.push(content.getContent());
}
setTime(time) {
this.mContents.time = time;
}
getLog() {
return this.mContents;
}
}
export class Content {
constructor(key, value) {
this.content = new cls.Log.Content({ key, value });
}
getContent() {
return this.content;
}
}
export declare function signature(secretId: string, secretKey: string, method: string, path: string, params: Map<string, string>, headers: Map<string, string>, expire: number): Promise<string>;
const getParamKeylist = function (obj) {
const list = [];
for (const key of obj.keys()) {
if (obj.has(key)) {
list.push(key);
}
}
return list.sort((a, b) => {
a = a.toLowerCase();
b = b.toLowerCase();
return a === b ? 0 : a > b ? 1 : -1;
});
};
const getHeaderKeylist = function (obj) {
const list = [];
for (const key of obj.keys()) {
const lowerKey = key.toLowerCase();
if (obj.has(key) &&
(lowerKey === 'content-type' || lowerKey === 'content-md5' || lowerKey === 'host' || lowerKey[0] === 'x')) {
list.push(key);
}
}
return list.sort((a, b) => {
a = a.toLowerCase();
b = b.toLowerCase();
return a === b ? 0 : a > b ? 1 : -1;
});
};
const camSafeUrlEncode = function (str) {
return encodeURIComponent(str)
.replace(/!/g, '%21')
.replace(/'/g, '%27')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\*/g, '%2A');
};
const map2str = function (obj, getKeylist) {
let i;
let key;
let val;
const list = [];
const keyList = getKeylist(obj);
for (i = 0; i < keyList.length; i++) {
key = keyList[i];
val = obj.get(key) === undefined ? '' : `${obj.get(key)}`;
key = key.toLowerCase();
key = camSafeUrlEncode(key);
val = camSafeUrlEncode(val) || '';
list.push(`${key}=${val}`);
}
return list.join('&');
};
export async function signature(secretId, secretKey, method, path, params, headers, expire) {
let now = Math.floor(Date.now() / 1000);
const exp = now + expire;
now = now - 60;
const qSignAlgorithm = 'sha1';
const qAk = secretId;
const qSignTime = `${now};${exp}`;
const qpathTime = qSignTime;
const qHeaderList = getHeaderKeylist(headers)?.join(';').toLowerCase();
const qUrlParamList = getParamKeylist(params)?.join(';').toLowerCase();
const encoder = new TextEncoder();
const algorithm = { name: 'HMAC', hash: 'SHA-1' };
const pathKey = await crypto.subtle.importKey('raw', encoder.encode(secretKey), algorithm, false, ['sign', 'verify']);
const pathSignature = await crypto.subtle.sign(algorithm.name, pathKey, encoder.encode(qpathTime));
const pathHashArray = Array.from(new Uint8Array(pathSignature));
const signpath = pathHashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
const formatString = [
method.toLowerCase(),
path,
map2str(params, getParamKeylist),
map2str(headers, getHeaderKeylist),
'',
].join('\n');
const resDigest = await crypto.subtle.digest(algorithm.hash, encoder.encode(formatString));
const resHashArray = Array.from(new Uint8Array(resDigest));
const res = resHashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
const stringToSign = ['sha1', qSignTime, res, ''].join('\n');
const qSignKey = await crypto.subtle.importKey('raw', encoder.encode(signpath), algorithm, false, ['sign', 'verify']);
const qSignSignature = await crypto.subtle.sign(algorithm.name, qSignKey, encoder.encode(stringToSign));
const qSignHashArray = Array.from(new Uint8Array(qSignSignature));
const qSignature = qSignHashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
const authorization = [
`q-sign-algorithm=${qSignAlgorithm}`,
`q-ak=${qAk}`,
`q-sign-time=${qSignTime}`,
`q-key-time=${qpathTime}`,
`q-header-list=${qHeaderList}`,
`q-url-param-list=${qUrlParamList}`,
`q-signature=${qSignature}`,
].join('&');
return authorization;
}
export default class TencentCloudClsSDKException extends Error {
requestId: string;
httpCode?: number;
code?: string;
constructor(error: string, requestId?: string);
getMessage(): string;
getRequestId(): string;
toString(): string;
toLocaleString(): string;
}
export default class TencentCloudClsSDKException extends Error {
constructor(error, requestId = '') {
super(error);
this.requestId = requestId || '';
}
getMessage() {
return this.message;
}
getRequestId() {
return this.requestId;
}
toString() {
return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`;
}
toLocaleString() {
return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`;
}
}
export { PutLogsRequest } from './request/putLogsRequest';
export { Response } from './response/response';
export { LogGroup, LogItem, Content } from './common/log';
export { AsyncClientOptions } from './models/options';
export { AsyncClient } from './asyncClient';
export { PutLogsRequest } from './request/putLogsRequest';
export { Response } from './response/response';
export { LogGroup, LogItem, Content } from './common/log';
export { AsyncClient } from './asyncClient';
export { AsyncClientOptions } from './options';
export interface AsyncClientOptions {
endpoint: string;
secretId: string;
secretKey: string;
sourceIp: string;
retry_times: number;
compress?: boolean;
}
import { LogGroup } from '../common/log';
import { Request } from './request';
export declare class PutLogsRequest extends Request {
private mTopic;
private mSource;
private mlogItems;
constructor(topic: string, logItems: LogGroup);
getFilename(): string;
setFilename(filename: string): void;
getTopic(): string;
setTopic(topic: string): void;
getSource(): string;
setSource(source: string): void;
getLogItems(): LogGroup;
setlogItems(logItems: LogGroup): void;
getLogGroupBytes(source: string): Uint8Array;
}
import { Request } from './request';
export class PutLogsRequest extends Request {
constructor(topic, logItems) {
super();
this.mTopic = topic;
this.mlogItems = logItems;
}
getFilename() {
return this.mlogItems.getFilename();
}
setFilename(filename) {
this.mlogItems.setFilename(filename);
}
getTopic() {
return this.mTopic;
}
setTopic(topic) {
this.mTopic = topic;
}
getSource() {
return this.mSource;
}
setSource(source) {
this.mSource = source;
}
getLogItems() {
return this.mlogItems;
}
setlogItems(logItems) {
this.mlogItems = logItems;
}
getLogGroupBytes(source) {
this.mlogItems.setSource(source);
return this.mlogItems.encode();
}
}
export declare class Request {
private mParams;
getParam(key: string): string;
setParam(key: string, value: string): void;
getAllParams(): Map<string, string>;
}
export class Request {
constructor() {
this.mParams = new Map();
}
getParam(key) {
if (this.mParams.has(key)) {
return this.mParams.get(key) || '';
}
return '';
}
setParam(key, value) {
if (value === null) {
this.mParams.set(key, '');
}
else {
this.mParams.set(key, value);
}
}
getAllParams() {
return this.mParams;
}
}
import { Request } from './request';
export declare class SearchLogRequest extends Request {
TopicId: string;
LogsetId: string;
StartTime: string;
EndTime: string;
QueryString: string;
Limit: string;
Context: string | undefined;
Sort: string;
constructor(topicId: string, logsetId: string, startTime: string, endTime: string, queryString: string, limit: string, context?: string, sort?: string);
}
import { Request } from './request';
export class SearchLogRequest extends Request {
constructor(topicId, logsetId, startTime, endTime, queryString, limit, context, sort) {
super();
this.TopicId = topicId;
this.LogsetId = logsetId;
this.StartTime = startTime;
this.EndTime = endTime;
this.QueryString = queryString;
this.Limit = limit;
this.Context = context;
if (sort === undefined) {
this.Sort = 'desc';
}
}
}
export declare class Response {
private httpStatusCode;
private mHeaders;
getHeader(key: string): any[];
setHttpStatusCode(code: number): void;
getHttpStatusCode(): number;
setAllHeaders(headers: {
[key: string]: any;
}): void;
getAllHeaders(): {
[key: string]: any;
};
}
export class Response {
constructor() {
this.httpStatusCode = 0;
this.mHeaders = {};
}
getHeader(key) {
return this.mHeaders[key] ? this.mHeaders[key] : [];
}
setHttpStatusCode(code) {
this.httpStatusCode = code;
}
getHttpStatusCode() {
return this.httpStatusCode;
}
setAllHeaders(headers) {
this.mHeaders = headers;
}
getAllHeaders() {
return this.mHeaders;
}
}
+2
-2
{
"name": "@edgeone/ef-cls-sdk",
"version": "1.0.0",
"description": "Edgefunction CLS SDK",
"version": "1.0.1",
"description": "Edgefunctions CLS SDK",
"main": "dist/index.js",

@@ -6,0 +6,0 @@ "types": "dist/index.d.ts",

# @edgeone/ef-cls-sdk
基于 [tencentcloud-cls-sdk-js](https://github.com/TencentCloud/tencentcloud-cls-sdk-js.git) 进行开发,适配 EdgeFunctions Runtime API,用于在边缘函数中进行 [CLS](https://cloud.tencent.com/document/product/614) 日志上报。
基于 [tencentcloud-cls-sdk-js](https://github.com/TencentCloud/tencentcloud-cls-sdk-js.git) 进行开发,适配 EdgeFunctions Runtime API,用于在 EdgeOne 边缘函数中进行 [CLS](https://cloud.tencent.com/document/product/614) 日志上报。

@@ -11,4 +11,2 @@ ## 安装

## 使用

@@ -37,3 +35,3 @@

async function clsUpload(data) {
async function clsUpload(data: string) {
const logGroup = new LogGroup();

@@ -52,3 +50,3 @@ const logItem = new LogItem();

async function doClsUpload(request) {
async function doClsUpload(request: Request) {
try {

@@ -62,3 +60,3 @@ const data = await request.clone().text();

async function handleRequest(event) {
async function handleRequest(event: FetchEvent) {
const { request } = event;

@@ -78,4 +76,2 @@ const contentType = request.headers.get('content-type') || '';

## 文档

@@ -82,0 +78,0 @@

import { AsyncClientOptions } from './models';
import { PutLogsRequest } from './request/putLogsRequest';
import { SearchLogRequest } from './request/searchResquest';
export declare class AsyncClient {
private httpType;
private hostName;
private secretId;
private secretKey;
private sourceIp;
private retry_times;
constructor(options: AsyncClientOptions);
PutLogs(request: PutLogsRequest): Promise<any>;
SearchLog(request: SearchLogRequest): Promise<any>;
private sendLogs;
private getCommonHeadPara;
}
import TencentCloudClsSDKException from './exception';
import { CONST_CONTENT_LENGTH, CONST_CONTENT_TYPE, CONST_HOST, CONST_JSON, CONST_PROTO_BUF, CONST_MAX_PUT_SIZE, TOPIC_ID, SORT, CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, CONST_AUTHORIZATION, TOPIC_IDS, START_TIME, END_TIME, LOGSET_ID, LIMIT, CONTEXT, CONST_HTTP_METHOD_GET, QUERY_STRING, } from './common/constants';
import { signature } from './common/sign';
import { Response } from './response/response';
export class AsyncClient {
constructor(options) {
if (options == null || options == undefined) {
throw new TencentCloudClsSDKException('AsyncClientOptions invalid');
}
if (options.endpoint == null || options.endpoint == undefined || options.endpoint.length == 0) {
throw new TencentCloudClsSDKException('options endpoint can not be empty');
}
if (options.secretId == null || options.secretId == undefined || options.secretId.length == 0) {
throw new TencentCloudClsSDKException('options secretId can not be empty');
}
if (options.secretKey == null || options.secretKey == undefined || options.secretKey.length == 0) {
throw new TencentCloudClsSDKException('options secretKey can not be empty');
}
if (options.sourceIp == null || options.sourceIp == undefined || options.sourceIp.length == 0) {
throw new TencentCloudClsSDKException('options sourceIp can not be empty');
}
this.retry_times = options.retry_times;
if (options.retry_times == 0 || options.retry_times == undefined || options.retry_times == null) {
this.retry_times = 5;
}
if (options.endpoint.startsWith('http://')) {
this.hostName = options.endpoint.substring(7);
this.httpType = 'http://';
}
else if (options.endpoint.startsWith('https://')) {
this.hostName = options.endpoint.substring(8);
this.httpType = 'https://';
}
else {
this.hostName = options.endpoint;
this.httpType = 'http://';
}
while (this.hostName.endsWith('/')) {
this.hostName = this.hostName.substring(0, this.hostName.length - 1);
}
if (options.compress) {
}
this.secretId = options.secretId;
this.secretKey = options.secretKey;
this.sourceIp = options.sourceIp;
}
async PutLogs(request) {
const logBytes = request.getLogGroupBytes(this.sourceIp);
if (logBytes.length > CONST_MAX_PUT_SIZE) {
throw new TencentCloudClsSDKException(`InvalidLogSize. logItems' size exceeds maximum limitation : ${CONST_MAX_PUT_SIZE} bytes, logBytes=${logBytes.length}, topic=${request.getTopic()}`);
}
const headParameter = this.getCommonHeadPara(CONST_PROTO_BUF);
request.setParam(TOPIC_ID, request.getTopic());
const urlParameter = request.getAllParams();
for (let retryTimes = 0; retryTimes < this.retry_times; retryTimes++) {
try {
const res = await this.sendLogs(CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, urlParameter, headParameter, logBytes, request.getTopic());
const putLogRequest = new Response();
putLogRequest.setAllHeaders(res.headers);
putLogRequest.setHttpStatusCode(res.status);
if (putLogRequest.getHttpStatusCode() == 200) {
return putLogRequest;
}
if (retryTimes + 1 >= this.retry_times) {
throw new TencentCloudClsSDKException('send log failed and exceed retry times');
}
}
catch (error) {
if (error.response && error.response.status == 413) {
const putLogRequest = new Response();
putLogRequest.setAllHeaders(error.response.headers);
putLogRequest.setHttpStatusCode(error.response.status);
return putLogRequest;
}
if (retryTimes + 1 >= this.retry_times) {
const putLogRequest = new Response();
if (error.response) {
putLogRequest.setAllHeaders(error.response.headers);
putLogRequest.setHttpStatusCode(error.response.status);
}
throw new TencentCloudClsSDKException(`send log failed and exceed retry times. error: ${error.message}. request: ${JSON.stringify(putLogRequest)}`);
}
}
}
}
async SearchLog(request) {
if (request.LogsetId == null || request.LogsetId == undefined || request.LogsetId.length == 0) {
throw new TencentCloudClsSDKException('logset_id can not be empty');
}
if (request.TopicId == null || request.TopicId == undefined || request.TopicId.length == 0) {
throw new TencentCloudClsSDKException('topic_id can not be empty');
}
if (request.StartTime == null || request.StartTime == undefined || request.StartTime.length == 0) {
throw new TencentCloudClsSDKException('start_time can not be empty');
}
if (request.EndTime == null || request.EndTime == undefined || request.EndTime.length == 0) {
throw new TencentCloudClsSDKException('end_time can not be empty');
}
if (request.Limit == null ||
request.Limit == undefined ||
request.Limit.length == 0 ||
parseInt(request.Limit, 10) > 100) {
throw new TencentCloudClsSDKException('sort parameter is invalid');
}
if (request.Sort != 'asc' && request.Sort != 'desc') {
throw new TencentCloudClsSDKException('sort parameter is invalid');
}
const urlParameter = request.getAllParams();
urlParameter.set(TOPIC_IDS, request.TopicId);
urlParameter.set(LOGSET_ID, request.LogsetId);
urlParameter.set(START_TIME, request.StartTime);
urlParameter.set(END_TIME, request.EndTime);
urlParameter.set(LIMIT, request.Limit);
urlParameter.set(QUERY_STRING, request.QueryString);
if (request.Context != null && request.Context != undefined && request.Context.length > 0) {
urlParameter.set(CONTEXT, request.Context);
}
urlParameter.set(SORT, request.Sort);
const headParameter = this.getCommonHeadPara(CONST_JSON);
headParameter.delete(CONST_CONTENT_LENGTH);
const signature_str = await signature(this.secretId, this.secretKey, CONST_HTTP_METHOD_GET, '/searchlog', new Map(), headParameter, 300000);
headParameter.set(CONST_AUTHORIZATION, signature_str);
const headers = {};
headParameter.forEach((value, key) => {
headers[key] = value;
});
let uri = '';
urlParameter.forEach((value, key) => {
uri += `${key}=${encodeURIComponent(value)}&`;
});
uri = uri.substring(0, uri.length - 1);
return fetch(`${this.httpType + this.hostName}/searchlog` + `?${uri}`, {
method: 'GET',
headers,
});
}
async sendLogs(method, resourceUri, urlParameter, headParameter, body, topic) {
headParameter.set(CONST_CONTENT_LENGTH, body.length.toString());
const signature_str = await signature(this.secretId, this.secretKey, method, resourceUri, urlParameter, headParameter, 300000);
headParameter.set(CONST_AUTHORIZATION, signature_str);
const headers = {};
headParameter.forEach((value, key) => {
headers[key] = value;
});
return fetch(`${this.httpType + this.hostName + resourceUri}?${TOPIC_ID}=${topic}`, {
method: 'POST',
body,
headers,
});
}
getCommonHeadPara(contentType) {
const headParameter = new Map();
headParameter.set(CONST_CONTENT_LENGTH, '0');
headParameter.set(CONST_CONTENT_TYPE, contentType);
headParameter.set(CONST_HOST, this.hostName);
return headParameter;
}
}
export declare const CONST_CONTENT_TYPE = "Content-Type";
export declare const CONST_PROTO_BUF = "application/x-protobuf";
export declare const CONST_JSON = "application/json";
export declare const CONST_CONTENT_LENGTH = "Content-Length";
export declare const CONST_AUTHORIZATION = "Authorization";
export declare const CONST_GZIP_ENCODING = "deflate";
export declare const CONST_HTTP_METHOD_POST = "POST";
export declare const CONST_HTTP_METHOD_GET = "GET";
export declare const CONST_X_SLS_REQUESTID = "x-log-requestid";
export declare const CONST_HOST = "Host";
export declare const CONST_MD5 = "MD5";
export declare const UTF_8_ENCODING = "UTF-8";
export declare const CONST_LOCAL_IP = "127.0.0.1";
export declare const HTTP_CONNECT_TIME_OUT: number;
export declare const HTTP_SEND_TIME_OUT: number;
export declare const TOPIC_ID = "topic_id";
export declare const UPLOAD_LOG_RESOURCE_URI = "/structuredlog";
export declare const CONST_MAX_PUT_SIZE: number;
export declare const CONST_X_SLS_COMPRESSTYPE = "x-cls-compress-type";
export declare const CONST_LZ4 = "lz4";
export declare const TOPIC_IDS = "topic_ids";
export declare const LOGSET_ID = "logset_id";
export declare const START_TIME = "start_time";
export declare const END_TIME = "end_time";
export declare const QUERY_STRING = "query_string";
export declare const LIMIT = "limit";
export declare const CONTEXT = "context";
export declare const SORT = "sort";
export const CONST_CONTENT_TYPE = 'Content-Type';
export const CONST_PROTO_BUF = 'application/x-protobuf';
export const CONST_JSON = 'application/json';
export const CONST_CONTENT_LENGTH = 'Content-Length';
export const CONST_AUTHORIZATION = 'Authorization';
export const CONST_GZIP_ENCODING = 'deflate';
export const CONST_HTTP_METHOD_POST = 'POST';
export const CONST_HTTP_METHOD_GET = 'GET';
export const CONST_X_SLS_REQUESTID = 'x-log-requestid';
export const CONST_HOST = 'Host';
export const CONST_MD5 = 'MD5';
export const UTF_8_ENCODING = 'UTF-8';
export const CONST_LOCAL_IP = '127.0.0.1';
export const HTTP_CONNECT_TIME_OUT = 60 * 1000;
export const HTTP_SEND_TIME_OUT = 60 * 1000;
export const TOPIC_ID = 'topic_id';
export const UPLOAD_LOG_RESOURCE_URI = '/structuredlog';
export const CONST_MAX_PUT_SIZE = 1 * 1024 * 1024;
export const CONST_X_SLS_COMPRESSTYPE = 'x-cls-compress-type';
export const CONST_LZ4 = 'lz4';
export const TOPIC_IDS = 'topic_ids';
export const LOGSET_ID = 'logset_id';
export const START_TIME = 'start_time';
export const END_TIME = 'end_time';
export const QUERY_STRING = 'query_string';
export const LIMIT = 'limit';
export const CONTEXT = 'context';
export const SORT = 'sort';
import { cls } from '../../vendor/compiled';
export declare class LogGroup {
mLogs: cls.LogGroup;
constructor();
getFilename(): string;
setFilename(filename: string): void;
getSource(): string;
setSource(source: string): void;
addLogs(log: LogItem): void;
encode(): Uint8Array;
decode(buffer: Uint8Array): {
[key: string]: any;
};
verify(buffer: Uint8Array): string | null;
}
export declare class LogItem {
mContents: cls.Log;
constructor();
pushBack(content: Content): void;
setTime(time: number): void;
getLog(): cls.Log;
}
export declare class Content {
content: cls.Log.Content;
constructor(key: string, value: string);
getContent(): cls.Log.Content;
}
import { cls } from '../../vendor/compiled';
export class LogGroup {
constructor() {
this.mLogs = new cls.LogGroup();
}
getFilename() {
return this.mLogs.filename || '';
}
setFilename(filename) {
this.mLogs.filename = filename;
}
getSource() {
return this.mLogs.source || '';
}
setSource(source) {
this.mLogs.source = source;
}
addLogs(log) {
this.mLogs.logs.push(log.getLog());
}
encode() {
const list = new cls.LogGroupList();
list.logGroupList.push(this.mLogs);
return cls.LogGroupList.encode(list).finish();
}
decode(buffer) {
return cls.LogGroupList.decode(buffer).toJSON();
}
verify(buffer) {
return cls.LogGroupList.verify(buffer);
}
}
export class LogItem {
constructor() {
this.mContents = new cls.Log();
}
pushBack(content) {
this.mContents.contents.push(content.getContent());
}
setTime(time) {
this.mContents.time = time;
}
getLog() {
return this.mContents;
}
}
export class Content {
constructor(key, value) {
this.content = new cls.Log.Content({ key, value });
}
getContent() {
return this.content;
}
}
export declare function signature(secretId: string, secretKey: string, method: string, path: string, params: Map<string, string>, headers: Map<string, string>, expire: number): Promise<string>;
const getParamKeylist = function (obj) {
const list = [];
for (const key of obj.keys()) {
if (obj.has(key)) {
list.push(key);
}
}
return list.sort((a, b) => {
a = a.toLowerCase();
b = b.toLowerCase();
return a === b ? 0 : a > b ? 1 : -1;
});
};
const getHeaderKeylist = function (obj) {
const list = [];
for (const key of obj.keys()) {
const lowerKey = key.toLowerCase();
if (obj.has(key) &&
(lowerKey === 'content-type' || lowerKey === 'content-md5' || lowerKey === 'host' || lowerKey[0] === 'x')) {
list.push(key);
}
}
return list.sort((a, b) => {
a = a.toLowerCase();
b = b.toLowerCase();
return a === b ? 0 : a > b ? 1 : -1;
});
};
const camSafeUrlEncode = function (str) {
return encodeURIComponent(str)
.replace(/!/g, '%21')
.replace(/'/g, '%27')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\*/g, '%2A');
};
const map2str = function (obj, getKeylist) {
let i;
let key;
let val;
const list = [];
const keyList = getKeylist(obj);
for (i = 0; i < keyList.length; i++) {
key = keyList[i];
val = obj.get(key) === undefined ? '' : `${obj.get(key)}`;
key = key.toLowerCase();
key = camSafeUrlEncode(key);
val = camSafeUrlEncode(val) || '';
list.push(`${key}=${val}`);
}
return list.join('&');
};
export async function signature(secretId, secretKey, method, path, params, headers, expire) {
let now = Math.floor(Date.now() / 1000);
const exp = now + expire;
now = now - 60;
const qSignAlgorithm = 'sha1';
const qAk = secretId;
const qSignTime = `${now};${exp}`;
const qpathTime = qSignTime;
const qHeaderList = getHeaderKeylist(headers)?.join(';').toLowerCase();
const qUrlParamList = getParamKeylist(params)?.join(';').toLowerCase();
const encoder = new TextEncoder();
const algorithm = { name: 'HMAC', hash: 'SHA-1' };
const pathKey = await crypto.subtle.importKey('raw', encoder.encode(secretKey), algorithm, false, ['sign', 'verify']);
const pathSignature = await crypto.subtle.sign(algorithm.name, pathKey, encoder.encode(qpathTime));
const pathHashArray = Array.from(new Uint8Array(pathSignature));
const signpath = pathHashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
const formatString = [
method.toLowerCase(),
path,
map2str(params, getParamKeylist),
map2str(headers, getHeaderKeylist),
'',
].join('\n');
const resDigest = await crypto.subtle.digest(algorithm.hash, encoder.encode(formatString));
const resHashArray = Array.from(new Uint8Array(resDigest));
const res = resHashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
const stringToSign = ['sha1', qSignTime, res, ''].join('\n');
const qSignKey = await crypto.subtle.importKey('raw', encoder.encode(signpath), algorithm, false, ['sign', 'verify']);
const qSignSignature = await crypto.subtle.sign(algorithm.name, qSignKey, encoder.encode(stringToSign));
const qSignHashArray = Array.from(new Uint8Array(qSignSignature));
const qSignature = qSignHashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
const authorization = [
`q-sign-algorithm=${qSignAlgorithm}`,
`q-ak=${qAk}`,
`q-sign-time=${qSignTime}`,
`q-key-time=${qpathTime}`,
`q-header-list=${qHeaderList}`,
`q-url-param-list=${qUrlParamList}`,
`q-signature=${qSignature}`,
].join('&');
return authorization;
}
export default class TencentCloudClsSDKException extends Error {
requestId: string;
httpCode?: number;
code?: string;
constructor(error: string, requestId?: string);
getMessage(): string;
getRequestId(): string;
toString(): string;
toLocaleString(): string;
}
export default class TencentCloudClsSDKException extends Error {
constructor(error, requestId = '') {
super(error);
this.requestId = requestId || '';
}
getMessage() {
return this.message;
}
getRequestId() {
return this.requestId;
}
toString() {
return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`;
}
toLocaleString() {
return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`;
}
}
export { PutLogsRequest } from './request/putLogsRequest';
export { Response } from './response/response';
export { LogGroup, LogItem, Content } from './common/log';
export { AsyncClientOptions } from './models/options';
export { AsyncClient } from './asyncClient';
export { PutLogsRequest } from './request/putLogsRequest';
export { Response } from './response/response';
export { LogGroup, LogItem, Content } from './common/log';
export { AsyncClient } from './asyncClient';
export { AsyncClientOptions } from './options';
export interface AsyncClientOptions {
endpoint: string;
secretId: string;
secretKey: string;
sourceIp: string;
retry_times: number;
compress?: boolean;
}
import { LogGroup } from '../common/log';
import { Request } from './request';
export declare class PutLogsRequest extends Request {
private mTopic;
private mSource;
private mlogItems;
constructor(topic: string, logItems: LogGroup);
getFilename(): string;
setFilename(filename: string): void;
getTopic(): string;
setTopic(topic: string): void;
getSource(): string;
setSource(source: string): void;
getLogItems(): LogGroup;
setlogItems(logItems: LogGroup): void;
getLogGroupBytes(source: string): Uint8Array;
}
import { Request } from './request';
export class PutLogsRequest extends Request {
constructor(topic, logItems) {
super();
this.mTopic = topic;
this.mlogItems = logItems;
}
getFilename() {
return this.mlogItems.getFilename();
}
setFilename(filename) {
this.mlogItems.setFilename(filename);
}
getTopic() {
return this.mTopic;
}
setTopic(topic) {
this.mTopic = topic;
}
getSource() {
return this.mSource;
}
setSource(source) {
this.mSource = source;
}
getLogItems() {
return this.mlogItems;
}
setlogItems(logItems) {
this.mlogItems = logItems;
}
getLogGroupBytes(source) {
this.mlogItems.setSource(source);
return this.mlogItems.encode();
}
}
export declare class Request {
private mParams;
getParam(key: string): string;
setParam(key: string, value: string): void;
getAllParams(): Map<string, string>;
}
export class Request {
constructor() {
this.mParams = new Map();
}
getParam(key) {
if (this.mParams.has(key)) {
return this.mParams.get(key) || '';
}
return '';
}
setParam(key, value) {
if (value === null) {
this.mParams.set(key, '');
}
else {
this.mParams.set(key, value);
}
}
getAllParams() {
return this.mParams;
}
}
import { Request } from './request';
export declare class SearchLogRequest extends Request {
TopicId: string;
LogsetId: string;
StartTime: string;
EndTime: string;
QueryString: string;
Limit: string;
Context: string | undefined;
Sort: string;
constructor(topicId: string, logsetId: string, startTime: string, endTime: string, queryString: string, limit: string, context?: string, sort?: string);
}
import { Request } from './request';
export class SearchLogRequest extends Request {
constructor(topicId, logsetId, startTime, endTime, queryString, limit, context, sort) {
super();
this.TopicId = topicId;
this.LogsetId = logsetId;
this.StartTime = startTime;
this.EndTime = endTime;
this.QueryString = queryString;
this.Limit = limit;
this.Context = context;
if (sort === undefined) {
this.Sort = 'desc';
}
}
}
export declare class Response {
private httpStatusCode;
private mHeaders;
getHeader(key: string): any[];
setHttpStatusCode(code: number): void;
getHttpStatusCode(): number;
setAllHeaders(headers: {
[key: string]: any;
}): void;
getAllHeaders(): {
[key: string]: any;
};
}
export class Response {
constructor() {
this.httpStatusCode = 0;
this.mHeaders = {};
}
getHeader(key) {
return this.mHeaders[key] ? this.mHeaders[key] : [];
}
setHttpStatusCode(code) {
this.httpStatusCode = code;
}
getHttpStatusCode() {
return this.httpStatusCode;
}
setAllHeaders(headers) {
this.mHeaders = headers;
}
getAllHeaders() {
return this.mHeaders;
}
}