API Script 手冊
Instana API Script 參照
Instana API Script 會與 Instana API 互動,以執行加強 Instana 監視能力的作業。 API Script 支援 Node.js 16。
廣域變數
Instana Synthetic API Script 使用下列預先定義的廣域變數來加速 Script 開發:
| API | 詳細資料 |
|---|---|
$http |
依要求模組傳送 HTTP 要求 (已淘汰) |
$got |
由取得的模組傳送 HTTP 要求 |
$secure |
存取使用者認證 |
$attributes |
管理自訂屬性 |
$network |
使用此網路公用程式來設定 Proxy |
$synthetic |
存取環境變數 |
$util |
使用公用程式功能,例如安全 API |
$http
在單一 API Script 中可以傳送一或多個要求。 Instana Synthetic API Script 使用預先定義的變數 $http 或 $got 來傳送 HTTP 要求。 $http 變數是以現在已淘汰的 request 模組為基礎。 此變數會暫時保留,稍後會在未來移除。
如需如何使用 $http的相關資訊,請參閱 API Script 手冊。
$已取得
若要避免未來移除 $http 時可能發生的問題,請使用 $got 變數從虛構 PoP 1.0.13傳送 HTTP 要求。 此變數使用 取得 模組。
如需如何使用 $got來傳送不同類型的 HTTP 要求的相關資訊,請參閱 撰寫 REST API 測試案例。
$secure
Instana API Script 支援使用者認證安全地儲存密碼,例如密碼或鑑別金鑰。
若要使用 API 來建立認證,請完成下列步驟:
- 請確定您具有適當的 許可權設定。
- 透過傳遞
credentialName和credentialValue,使用 Synthetic OpenAPI 來建立認證。
然後,在 API Script 中,使用 $secure.credentialName 來參照所建立的認證,例如 $secure.password 或 $secure.API_KEY。
$synthetic
您可以使用 $synthetic.var_name 來存取 Script 中的環境和執行時期變數。 請參閱下列預先定義的變數:
- $synthetic.LOCATION 或 $synthetic.pop: 用來存取 location 標籤,這是 controller.location 變數中的第一個組件。
- $synthetic.TEST_ID 或 $synthetic.id: 用來存取所執行虛構測試的 ID。
- $synthetic.TEST_NAME 或 $synthetic.testName: 用來存取所執行虛構測試的 test 標籤。
- $synthetic.TIME_ZONE 或 $synthetic.timeZone: 用來存取執行綜合測試之 PoP 的時區。
- $synthetic.JOB_ID 或 $synthetic.taskId: 用來存取播放作業的 ID ,它也是結果 ID。
- $synthetic.testType: 用來存取測試類型。
- $synthetic.description: 用來存取測試說明。
您也可以在 Helm Chart 的 values.yaml 中定義自訂環境變數。 請參閱下列範例:
controller:
customProperties: "tag1=value1;tag2=value2"
然後,在 Script 中使用 $synthetic.tag1 和 $synthetic.tag2 來存取這些自訂變數。
如果要存取測試定義的 customProperties 區段中定義的自訂內容,您可以使用 $synthetic.labels.xxx 來存取 Script 中的內容值。 請參閱下列範例:
// to print test custom tags/labels
console.log('Test Label $synthetic.labels.Team: ' + $synthetic.labels.Team);
console.log('Test Label $synthetic.labels.Purpose: ' + $synthetic.labels.Purpose);
$attributes
使用 $attributes 來新增或取得自訂屬性以監視資料。 API Script 開發人員可以將自訂 key/value 配對資料新增為自訂屬性。 自訂資料可作為預設屬性的新增項目。 這些自訂屬性也會與其他預設監視器結果屬性一起儲存在監視器結果中。 如果要存取自訂屬性,請使用 Instana API Script 中的 $attributes :
$attributes.set('tag1', 'value1') // sets tag tag1 to value value1
let v = $attributes.get('tag1') // sets variable v to the value of tag1
$network
在 Instana 虛構監視中支援下列 API ,以配置 Proxy 伺服器:
$network.setProxy(string proxy): 用來設定要用於所有要求的 Proxy 伺服器 (HTTP、HTTP)。$network.setProxyForHttp(string proxy): 用來設定 Proxy 伺服器只用於 HTTP 要求。$network.setProxyForHttps(string proxy): 用來設定 Proxy 伺服器只用於 HTTP 要求。$network.clearProxy(): 用來移除 Proxy 配置。$network.getProxy(): 用來傳回 Proxy 配置。
下列範例使用 Proxy:
const assert = require('assert');
// Proxy with ip:port
// $network.setProxy('http://proxyhost:port');
// $network.setProxyForHttp('http://proxyhost:port');
// $network.setProxyForHttps('http://proxyhost:port');
// Proxy with authentication, create proxyUser and proxyPass credentials first
$network.setProxy('http://' + $secure.proxyUser + ':' + $secure.proxyPass + '@proxyhost:port');
// retrieve proxy
// let proxy = $network.getProxy();
$util.secrets
使用此安全 API 來編寫機密資料。
在將所有已知機密性資訊寫入記載檔案並傳送至後端之前,會以 * 字元遮罩這些資訊。
虛構 PoP 不會收集 HTTP 標頭和內文資料。 如果您想要從 URL 編寫密鑰,請在 Script 中使用指令 $util.secrets.setURLSecretsRegExps 。 請參閱下列範例:
// to redact 'key', 'password' and 'secret' query parameters in URL
$util.secrets.setURLSecretsRegExps([/key/i, /password/i, /secret/i]);
呼叫此 API 之後,會收集 URL https://example.com/accounts/status?key=mykey123&secret=mysecret ,並在 Instana 使用者介面中顯示為 https://example.com/accounts/status?key=*&secret=* 。
撰寫 REST API 測試案例
如果要撰寫 REST API 測試案例,請完成下列步驟:
傳送 HTTP 要求。 下列範例顯示如何傳送 HTTP GET 及 POST 要求,並驗證其狀態碼及回應內文:
const assert = require('assert'); (async function () { // GET example const {statusCode} = await $got.get('https://httpbin.org/get'); assert.equal(statusCode, 200, 'Expected a 200 Status Code, current is ' + statusCode); // POST example var postOptions = { url: 'https://httpbin.org/post', json: { 'name': 'TestName', 'type': 'Synthetic Script' }, https:{ rejectUnauthorized: false }, headers:{'accept': 'application/json'} }; let postResponse = await $got.post(postOptions); assert.ok(postResponse.statusCode == 200, 'POST status is ' + postResponse.statusCode + ', it should be 200'); const jsonBody = JSON.parse(postResponse.body); assert.equal(jsonBody.json.name, 'TestName', 'Expected TestName'); assert.equal(jsonBody.json.type, 'Synthetic Script', 'Expected Synthetic Script'); })();依預設, Got 會在失敗時重試 2 次。 若要停用此選項,請將 options.retry 設為
{limit: 0}。若要驗證結果,請使用
const assert=require('assert');指令匯入assert模組,並呼叫assert方法來驗證端點回應。若要驗證回應 statusCode,請參閱下列範例:
const assert=require('assert'); assert.ok(response && response.statusCode == 200, 'Expected a 200 status code, statusCode is ' + response.statusCode); assert.equal(response.statusCode, 200, 'Expected a 200 status code')若要驗證回應內容,請參閱下列範例:
let bodyObj = (typeof body == 'string') ? JSON.parse(body) : body; assert.ok(bodyObj.id != null, 'id should not be null');若要除錯 Script ,請使用
console指令。 您可以在 Instana 使用者介面中查看日誌內容。console.info() console.log() console.error() console.warn()
傳送 GET HTTP 要求
若要傳送 GET 要求,請使用下列語法:
const assert = require('assert');
(async function () {
var options = {
url: 'https://reqres.in/api/messages',
https:{ rejectUnauthorized: false }
};
// Send GET request
let response = await $got.get(options);
// Validate the response status code, it should be 200 here
assert.ok(response && response.statusCode == 200, 'Expect 200');
})();
傳送 POST HTTP 要求
若要傳送 POST JSON 要求,請使用下列語法:
const assert = require('assert');
(async function () {
// Send JSON Data example
let URL = 'https://reqres.in/api/users';
// Define JSON data
let data = {
'job': 'leader',
'name': 'morpheus'
};
// Make POST request
let response = await $got.post(URL, {
header: {
'content-type': 'application/json'
},
json: data
});
// Validate the response code, if assertion fails, log "failed to create message, error is " plus
// results as error message on Synthetic dashboard
assert.ok(response && response.statusCode == 201, 'expect 201');
})();
若要傳送 POST 表單要求,請使用下列語法:
const assert = require('assert');
(async function () {
const response = await $got.post('https://httpbin.org/anything', {
form: {
text: 'hello world'
}
});
assert.ok(response && response.statusCode == 200, 'expect 200');
})();
傳送 TLS/SSL 支援要求
若要傳送 HTTP 要求並容許不安全的憑證,請使用下列語法:
// Allow the insecure certificate
await $got('https://example.com', {
https:{ rejectUnauthorized: false }
});
若要使用憑證來傳送「TLS/SSL 通訊協定」要求,請使用下列語法:
// Single key with passphrase
await $got('https://example.com', {
https: {
key: $secure.key,
certificate: $secure.certificate,
passphrase: $secure.passphrase
}
});
附註: 建立認證以儲存金鑰、憑證及通行詞組。
傳送基本鑑別要求
若要傳送基本鑑別要求,請使用下列語法:
await $got.get('http://some.server.com/', {
https:{ rejectUnauthorized: false },
headers: {
Authorization: "Basic " + $secure.AUTH_CRED
}
});
附註: 您需要建立認證變數 AUTH_CRED ,以儲存 HTTP 基本鑑別的使用者名稱和密碼。 AUTH_CRED 認證變數的格式是使用 base64編碼的 username:password 。
使用熊記號傳送要求
若要傳送熊鑑別要求,請使用下列語法:
await $got.get('http://some.server.com/', {
headers: {
'Authorization': "Bearer " + $secure.authToken
}
});
附註: 建立認證以儲存熊 authToken 文字。
管理模組
匯入選用模組
若要匯入支援的模組,請遵循關於 Node.js 匯入的標準程序。 請參閱下列範例:
const crypto = require('crypto-js');
支援的核心模組
支援的核心模組如下:
- 主張
- async_hooks
- 緩衝區 (buffer)
- 常數
- crypto
- dgram
- dns
- 網域
- 事件
- fs
- http
- http2
- https
- 模組
- net
- os
- 路徑
- perf_hooks
- Punycode
- queryString
- 串流
- 字串解碼器
- 計時器
- TLS
- trace_events
- tty
- url
- 使用率
- ZLib
支援的協力廠商模組
支援下列協力廠商模組:
- assert-plus 1.0.0
- atob 2.1.2
- @aws-sdk/client-s3 3.387.0
- @babel/core 7.23.2
- basic-ftp 4.6.6
- body-parser 1.20.0
- btoa 1.2.1
- 複製 0.1.19
- 顏色 1.4.0
- consoleplusplus 1.4.4
- crypto-js 4.2.0
- 除錯 2.6.9
- 延伸 3.0.2
- faker 5.5.3
- 取得 11.8.6
- joi 17.6.0
- js-yaml 3.14.1
- jsprim 1.4.2
- kafkajs 2.2.4
- ldapauth-fork 5.0.5
- lodash 4.17.21
- 時刻 2.29.4
- net-snmp 3.8.2
- node-stream-zip 1.15.0
- 舞用戶端 14.2.0
- protocol-緩衝區 4.2.0
- q 1.5.1
- 要求 2.88.2
- 應該 13.2.3
- sip 0.0.6
- ssh2-sftp-client 7.2.3
- sshpk 1.17.0
- ssl-checker 2.0.8
- swagger-parser 8.0.4
- 文字編碼 0.7.0
- Thrift 0.14.2
- 強硬 Cookie 4.1.3
- 底線 1.13.4
- un拉鍊 0.10.11
- url-parse 1.5.10
- urllib 2.41.0
- uuid 3.4.0
- 驗證器 13.7.0
- ws 7.5.8
- xml2js 0.5.0
在本端測試及除錯 API Script
synthetic-api-script 是在區域環境中開發及除錯 API Script 的節點模組。 如需相關資訊,請參閱 Readme 檔。
使用 script-cli 指令
若要測試及除錯 API Script ,請使用 script-cli 指令,如下列範例所示:
# Usage:
# test a single script
script-cli <script_name>
# test bundled scripts
script-cli -d <dir> <script-entry-file>
# Example:
script-cli examples/example1.js
script-cli -d examples/bundle-example1 index.js
建立單一 API Script 測試
建立虛構 Script 之後,請完成下列步驟:
使用
synthetic-api-script來建立 API Script ,並使用script-cli指令將 Script 轉換為字串:# Usage: script-cli -s <script-file-path> # Example: script-cli -s examples/got-get.js下列範例顯示結果:
{ "syntheticType":"HTTPScript", "script":"var assert = require('assert');\n\n(async function() {\n var options = {\n url: 'https://httpbin.org/get',\n https:{\n rejectUnauthorized: false\n }\n };\n\n let response = await $got.get(options);\n assert.equal(response.statusCode, 200, 'Expected a 200 OK response');\n console.log('Request URL %s, statusCode: %d', response.url, response.statusCode);\n})();\n" }複製並貼上 Script 內容,以建置下列範例 API Script 測試 JSON。
{ "label": "APIScript_Test", "active": true, "testFrequency": 1, "locations": ["DemoPoP1_saas_instana_test"], "configuration": { "syntheticType": "HTTPScript", "script": "converted script string" } }
建立組合 API Script 測試
如果商業邏輯很複雜,請勿在單一 Script 中包含所有內容,因為開發人員很難在 Git 儲存庫中管理多個 Script 檔。
若要建立組合 API Script 測試,請完成下列步驟:
使用 script-cli 指令來組合壓縮檔中的 Script:
# Usage: script-cli -z <bundle-script-folder> <entry-script> # Example: script-cli -z bundle-example1 bundle-example1/index.js以
script-cli指令的輸出來填寫測試配置中的scriptFile和bundle:scriptFile是組合 Script 的進入點。bundle是以 base64編碼的壓縮檔。
若要建立虛構組合測試,請填寫測試有效負載,如下列範例所示:
{
"label": "APIScriptBundle_Test",
"active": true,
"testFrequency": 5,
"locations": ["DemoPoP1_saas_instana_test"],
"configuration": {
"syntheticType": "HTTPScript",
"scripts": {
"scriptFile": "index.js",
"bundle": "zipped scripts encoded with base64"
}
}
}
Script 範例
範例 1: 用來測試 httpbin API 的 Instana API Script
您可以使用 Instana API Script ,以同步化方式來測試 httpbin API ,如下所示:
const assert = require('assert');
(async function () {
var getOptions = {
url: 'https://httpbin.org/get',
https:{ rejectUnauthorized: false },
headers: {
'Additional-Header': 'Additional-Header-Data'
}
};
let getResponse = await $got.get(getOptions);
console.info("Sample API - GET, response code: " + getResponse.statusCode);
assert.ok(getResponse.statusCode == 200, "GET status is " + getResponse.statusCode + ", it should be 200");
var bodyObj1 = JSON.parse(getResponse.body);
assert.ok(bodyObj1.url == "https://httpbin.org/get", "httpbin.org REST API GET URL verify failed");
var postOptions = {
url: 'https://httpbin.org/post',
json: {
"name1": "this is the first data",
"name2": "second data"
},
https:{ rejectUnauthorized: false },
headers:{"accept": "application/json"}
};
let postResponse = await $got.post(postOptions);
console.info("Sample API - POST, response code: " + postResponse.statusCode);
assert.ok(postResponse.statusCode == 200, 'POST status is ' + postResponse.statusCode + ', it should be 200');
const jsonBody2 = JSON.parse(postResponse.body);
assert.equal(jsonBody2.json.name1, 'this is the first data', 'Expected this is the first data');
assert.equal(jsonBody2.json.name2, 'second data', 'Expected second data');
var putOptions = {
url: 'https://httpbin.org/put',
json: {
"name1": 'this is the first data',
"name2": 'second data'
},
https:{ rejectUnauthorized: false },
headers:{"accept": "application/json"}
};
let putResponse = await $got.put(putOptions);
console.info("Sample API - PUT, response code: " + putResponse.statusCode);
assert.ok(putResponse.statusCode == 200, 'PUT status is ' + putResponse.statusCode + ', it should be 200');
const jsonBody3 = JSON.parse(putResponse.body);
assert.ok(jsonBody3.url == "https://httpbin.org/put", "httpbin.org REST API PUT URL verify failed");
assert.equal(jsonBody3.json.name2, 'second data', 'Expected second data');
var deleteOptions = {
url: 'https://httpbin.org/delete',
https:{ rejectUnauthorized: false },
headers:{"accept": "application/json"}
};
let deleteResponse = await $got.delete(deleteOptions);
console.info("Sample API - DELETE, response code: " + deleteResponse.statusCode);
assert.ok(deleteResponse.statusCode == 200, 'DELETE status is ' + deleteResponse.statusCode + ', it should be 200');
const jsonBody4 = JSON.parse(deleteResponse.body);
assert.ok(jsonBody4.url == "https://httpbin.org/delete", "httpbin.org REST API DELETE URL verify failed");
// to print environment variables
console.info('List PoP environment variables using $synthetic API');
console.info('Test ID:', $synthetic.TEST_ID);
console.info('Test Name:', $synthetic.TEST_NAME);
console.info('Location:', $synthetic.LOCATION);
console.info('TimeZone:', $synthetic.TIME_ZONE);
console.info('Job ID:', $synthetic.JOB_ID);
// to print test custom tags/labels
console.info('Test Label $synthetic.labels.Team: ' + $synthetic.labels.Team);
console.info('Test Label $synthetic.labels.Purpose: ' + $synthetic.labels.Purpose);
// to set custom tags dynamically
$attributes.set('custom_tag1', 'value1');
})();
範例 2: 用來測試網站憑證的 Instana API Script
您可以使用 Instana API Script 來測試 ibm.com 的 SSL 憑證,如下所示:
const sslChecker = require('ssl-checker');
const assert = require('assert');
const hostname = 'ibm.com';
const remainDays = 90;
const getSslDetails = async(hostname) => {
const result = await sslChecker(hostname);
console.log(`certificate is valid: ${result.valid}`);
console.log(`certificate expires on: ${result.validTo}`);
console.log(`certificate days remaining: ${result.daysRemaining}`);
assert.equal(result.valid, true, 'certificate of ibm should be valid');
// this script will fail if the certificate remaining days less than 90 days by default
// modify variable remainDays to any value as you need
assert.equal(result.daysRemaining >= remainDays, true, `certificate validated remain days is less than ${remainDays} days`);
};
getSslDetails(hostname);
如需其他 API Script 範例,請參閱 虛構 API Script。