指標
Prisma Client 指標為你提供了關於 Prisma Client 如何與你的資料庫互動的詳細資訊。你可以利用這些資訊來診斷應用程式的效能問題。
如果你想更詳細地瞭解 Prisma Client 的效能(甚至到單個操作的級別),請參閱追蹤。
關於指標
你可以以 JSON 或 Prometheus 格式匯出指標,並在控制檯日誌中檢視,或將其整合到外部指標系統,如 StatsD 或 Prometheus。如果將其整合到外部指標系統,則可以隨著時間推移檢視指標資料。例如,你可以使用指標來幫助診斷應用程式的空閒和活動連線數量如何變化。
Prisma Client 提供以下指標
-
計數器(總是增加)
prisma_client_queries_total: 執行的 Prisma Client 查詢總數。prisma_datasource_queries_total: 執行的資料來源查詢總數(關係型資料庫中的 SQL 查詢,以及 MongoDB 中的命令)。prisma_datasource_queries_total返回的值可能大於prisma_client_queries_total,因為某些 Prisma Client 操作會建立多個查詢。
prisma_pool_connections_closed_total: 關閉的連線池連線總數。prisma_pool_connections_opened_total: 當前開啟的連線池連線數。
-
儀表(可以增加或減少)
prisma_client_queries_active: 當前活動的 Prisma Client 查詢數量。prisma_client_queries_wait: 由於所有連線都在使用中,當前等待連線的 Prisma Client 查詢數量。prisma_pool_connections_busy: 當前正在忙碌的連線池連線數量。這些連線池連線正在執行資料來源查詢。prisma_pool_connections_idle: 當前未被使用的連線池連線數量。這些連線池連線正在等待下一次資料來源查詢執行。prisma_pool_connections_open: 開啟的連線池連線數量。
-
直方圖(指標資料分為一組值;我們稱集合中的每個容器為“桶”)
prisma_client_queries_wait_histogram_ms: 所有 Prisma Client 查詢等待連線池連線的時間(毫秒)。prisma_client_queries_duration_histogram_ms: 所有已執行的 Prisma Client 查詢的執行時間(毫秒)。這包括執行所有資料庫查詢,以及執行所有資料庫引擎活動(例如連線資料和將資料轉換為正確格式)所花費的時間。prisma_datasource_queries_duration_histogram_ms: 所有已執行的資料來源查詢的執行時間(毫秒)。
你可以為你的指標資料新增全域性標籤,以幫助你對指標進行分組和區分,例如按基礎設施區域或伺服器。
先決條件
要使用 Prisma Client 指標,你必須執行以下操作
1. 安裝最新的 Prisma ORM 依賴
使用 prisma 和 @prisma/client npm 包的 3.15.0 或更高版本。
npm install prisma@latest --save-dev
npm install @prisma/client@latest
2. 在 Prisma schema 檔案中啟用功能標誌
在你的 schema.prisma 檔案的 generator 塊中,啟用 metrics 功能標誌
generator client {
provider = "prisma-client-js"
previewFeatures = ["metrics"]
}
以 JSON 格式檢索指標
當你以 JSON 格式檢索指標時,你可以直接使用它們返回的格式,或者將它們傳送到 StatSD 以視覺化它們隨時間的變化。
要以 JSON 格式檢索指標,請將以下行新增到你的應用程式程式碼中
const metrics = await prisma.$metrics.json()
console.log(metrics)
這將按如下方式返回指標
{
"counters": [
{
"key": "prisma_client_queries_total",
"labels": {},
"value": 0,
"description": "Total number of Prisma Client queries executed"
},
{
"key": "prisma_datasource_queries_total",
"labels": {},
"value": 0,
"description": "Total number of Datasource Queries executed"
},
{
"key": "prisma_pool_connections_closed_total",
"labels": {},
"value": 0,
"description": "Total number of Pool Connections closed"
},
{
"key": "prisma_pool_connections_opened_total",
"labels": {},
"value": 1,
"description": "Total number of Pool Connections opened"
}
...
],
"gauges": [
...
],
"histograms": [
...
]
}
展開以檢視完整輸出
{
"counters": [
{
"key": "prisma_client_queries_total",
"labels": {},
"value": 2,
"description": "Total number of Prisma Client queries executed"
},
{
"key": "prisma_datasource_queries_total",
"labels": {},
"value": 5,
"description": "Total number of Datasource Queries executed"
},
{
"key": "prisma_pool_connections_open",
"labels": {},
"value": 1,
"description": "Number of currently open Pool Connections"
}
],
"gauges": [
{
"key": "prisma_client_queries_active",
"labels": {},
"value": 0,
"description": "Number of currently active Prisma Client queries"
},
{
"key": "prisma_client_queries_wait",
"labels": {},
"value": 0,
"description": "Number of Prisma Client queries currently waiting for a connection"
},
{
"key": "prisma_pool_connections_busy",
"labels": {},
"value": 0,
"description": "Number of currently busy Pool Connections (executing a datasource query)"
},
{
"key": "prisma_pool_connections_idle",
"labels": {},
"value": 21,
"description": "Number of currently unused Pool Connections (waiting for the next datasource query to run)"
},
{
"key": "prisma_pool_connections_open",
"labels": {},
"value": 1,
"description": "Number of currently open Pool Connections"
}
],
"histograms": [
{
"key": "prisma_client_queries_duration_histogram_ms",
"labels": {},
"value": {
"buckets": [
[0, 0],
[1, 0],
[5, 0],
[10, 1],
[50, 1],
[100, 0],
[500, 0],
[1000, 0],
[5000, 0],
[50000, 0]
],
"sum": 47.430541000000005,
"count": 2
},
"description": "Histogram of the duration of all executed Prisma Client queries in ms"
},
{
"key": "prisma_client_queries_wait_histogram_ms",
"labels": {},
"value": {
"buckets": [
[0, 0],
[1, 3],
[5, 0],
[10, 0],
[50, 0],
[100, 0],
[500, 0],
[1000, 0],
[5000, 0],
[50000, 0]
],
"sum": 0.0015830000000000002,
"count": 3
},
"description": "Histogram of the wait time of all Prisma Client Queries in ms"
},
{
"key": "prisma_datasource_queries_duration_histogram_ms",
"labels": {},
"value": {
"buckets": [
[0, 0],
[1, 0],
[5, 2],
[10, 2],
[50, 1],
[100, 0],
[500, 0],
[1000, 0],
[5000, 0],
[50000, 0]
],
"sum": 47.134498,
"count": 5
},
"description": "Histogram of the duration of all executed Datasource Queries in ms"
}
]
}
JSON 資料中的直方圖
每個直方圖“桶”有兩個值。第一個是桶的上限,第二個是計數(落入該桶的資料值的數量)。在以下示例中,11 到 20 之間的值有兩個例項,21 到 30 之間的值有五個例項
...
[20, 2],
[30, 5],
...
將 Prisma Client 指標與 StatsD 結合使用
你可以將 JSON 格式的指標傳送到 StatsD,以隨著時間推移視覺化你的指標資料。
注意:你必須將計數器指標作為一系列值提供給 StatsD,這些值從之前檢索的指標中遞增或遞減。然而,Prisma Client 的計數器指標返回的是絕對值。因此,你必須將計數器指標轉換為一系列遞增和遞減的值,並將其作為儀表資料傳送給 StatsD。在下面的程式碼示例中,我們使用 diffHistograms 將計數器指標轉換為遞增和遞減的儀表資料。
在以下示例中,我們每 10 秒向 StatsD 傳送一次指標。這個時間與 StatsD 預設的 10 秒重新整理率一致。
import StatsD from 'hot-shots'
let statsd = new StatsD({
port: 8125,
})
const diffMetrics = (metrics: Metric<MetricHistogram>[]) => {
return metrics.map((metric) => {
let prev = 0;
const diffBuckets = metric.value.buckets.map<MetricHistogramBucket>(
(values) => {
const [bucket, value] = values
const diff = value - prev
prev = value
return [bucket, diff]
}
)
metric.value.buckets = diffBuckets
return metric
})
}
let previousHistograms: Metric<MetricHistogram>[] = []
const statsdSender = async () => {
const metrics = await prisma.$metrics.json()
metrics.counters.forEach((counter: any) => {
statsd.gauge('prisma.' + counter.key, counter.value, (...res) => {})
});
metrics.gauges.forEach((counter: any) => {
statsd.gauge('prisma.' + counter.key, counter.value, (...res) => {})
})
if (!previousHistograms.length) {
previousHistograms = diffMetrics(metrics.histograms)
return
}
const diffHistograms = diffMetrics(metrics.histograms);
diffHistograms.forEach((diffHistogram, histogramIndex) => {
diffHistogram.value.buckets.forEach((values, bucketIndex) => {
const [bucket, count] = values
const [_, prev] =
previousHistograms[histogramIndex].value.buckets[bucketIndex]
const change = count - prev
for (let sendTimes = 0; sendTimes < change; sendTimes++) {
statsd.timing('prisma.' + diffHistograms.key, bucket)
}
})
})
previousHistograms = diffHistograms
}
setInterval(async () => await statsdSender(), 10000)
以 Prometheus 格式檢索指標
當你以 Prometheus 格式檢索 Prisma Client 指標時,你可以直接使用它們返回的格式,或者將它們傳送到 Prometheus 指標系統,以視覺化它們隨時間的變化。
要以 Prometheus 格式檢索指標,請將以下行新增到你的應用程式程式碼中
const metrics = await prisma.$metrics.prometheus()
console.log(metrics)
這將按如下方式返回指標
# HELP prisma_client_queries_total Total number of Prisma Client queries executed
# TYPE prisma_client_queries_total counter
prisma_client_queries_total 14
...
# HELP prisma_pool_connections_busy The number of active connections in use.
# TYPE prisma_pool_connections_busy gauge
prisma_pool_connections_busy 0
...
# HELP prisma_client_queries_wait_histogram_ms The wait time for a worker to get a connection.
# TYPE prisma_client_queries_wait_histogram_ms histogram
prisma_client_queries_wait_histogram_ms_bucket{le="0"} 0
prisma_client_queries_wait_histogram_ms_bucket{le="1"} 3
展開以檢視完整輸出
# HELP query_total_operations
# TYPE query_total_operations counter
query_total_operations 2
# HELP prisma_datasource_queries_total
# TYPE prisma_datasource_queries_total counter
prisma_datasource_queries_total 28
# HELP prisma_pool_connections_closed_total Total number of Pool Connections closed
# TYPE prisma_pool_connections_closed_total counter
prisma_pool_connections_closed_total 0
# HELP prisma_pool_connections_opened_total Total number of Pool Connections opened
# TYPE prisma_pool_connections_opened_total counter
prisma_pool_connections_opened_total 0
# HELP prisma_client_queries_active Number of currently active Prisma Client queries
# TYPE prisma_client_queries_active gauge
prisma_client_queries_active 0
# HELP prisma_client_queries_wait Number of queries currently waiting for a connection
# TYPE prisma_client_queries_wait gauge
prisma_client_queries_wait 0
# HELP prisma_pool_connections_busy Number of currently busy Pool Connections (executing a datasource query)
# TYPE prisma_pool_connections_busy gauge
prisma_pool_connections_busy 0
# HELP prisma_pool_connections_idle Number of currently unused Pool Connections (waiting for the next pool query to run)
# TYPE prisma_pool_connections_idle gauge
prisma_pool_connections_idle 21
# HELP prisma_pool_connections_open Number of currently open Pool Connections
# TYPE prisma_pool_connections_open gauge
prisma_pool_connections_open 1
# HELP prisma_pool_connections_open Number of currently open Pool Connections (able to execute a datasource query)
# TYPE prisma_pool_connections_open gauge
prisma_pool_connections_open 0
# HELP prisma_client_queries_wait_histogram_ms The wait time for a worker to get a connection.
# TYPE prisma_client_queries_wait_histogram_ms histogram
prisma_client_queries_wait_histogram_ms_bucket{le="0"} 0
prisma_client_queries_wait_histogram_ms_bucket{le="1"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="5"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="10"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="50"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="100"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="500"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="1000"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="5000"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="50000"} 3
prisma_client_queries_wait_histogram_ms_bucket{le="+Inf"} 3
prisma_client_queries_wait_histogram_ms_sum 0.023208
prisma_client_queries_wait_histogram_ms_count 3
# HELP prisma_client_queries_duration_histogram_ms Histogram of the duration of all executed Prisma Client queries in ms
# TYPE prisma_client_queries_duration_histogram_ms histogram
prisma_client_queries_duration_histogram_ms_bucket{le="0"} 0
prisma_client_queries_duration_histogram_ms_bucket{le="1"} 1
prisma_client_queries_duration_histogram_ms_bucket{le="5"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="10"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="50"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="100"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="500"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="1000"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="5000"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="50000"} 2
prisma_client_queries_duration_histogram_ms_bucket{le="+Inf"} 2
prisma_client_queries_duration_histogram_ms_sum 3.197624
prisma_client_queries_duration_histogram_ms_count 2
# HELP prisma_datasource_queries_duration_histogram_ms Histogram of the duration of all executed Datasource Queries in ms
# TYPE prisma_datasource_queries_duration_histogram_ms histogram
prisma_datasource_queries_duration_histogram_ms_bucket{le="0"} 0
prisma_datasource_queries_duration_histogram_ms_bucket{le="1"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="5"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="10"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="50"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="100"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="500"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="1000"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="5000"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="50000"} 5
prisma_datasource_queries_duration_histogram_ms_bucket{le="+Inf"} 5
prisma_datasource_queries_duration_histogram_ms_sum 1.8407059999999997
prisma_datasource_queries_duration_histogram_ms_count 5
型別為 histogram 的指標以 Prometheus 格式公開三種不同類別的值
-
觀察桶的多個累積計數器。這些計數器以後綴
_bucket{le="<上限(包含)>"}結尾。例如,prisma_datasource_queries_duration_histogram_ms有一個計數器公開為prisma_datasource_queries_duration_histogram_ms_bucket{le="1"}當觀察到的值小於或等於桶的上限(包含)時,Prisma Client 指標將該桶加 1。假設你有的桶的上限(包含)分別為 0、1、5、10 和 50。如果觀察到的值為 5,則 Prisma Client 指標將從第三個桶開始遞增,因為該值大於 0 和 1,但小於或等於 5、10 和 50。
-
所有觀測值的單個總和。此計數器以後綴
_sum結尾。例如,prisma_datasource_queries_duration_histogram_ms的總和公開為prisma_datasource_queries_duration_histogram_ms_sum。 -
已觀察事件數量的計數。此計數器以後綴
_count結尾。例如,prisma_datasource_queries_duration_histogram_ms事件的總計數公開為prisma_datasource_queries_duration_histogram_ms_count。
有關更多資訊,請閱讀 Prometheus 文件中關於指標型別的內容。
將 Prisma Client 指標與 Prometheus 指標系統結合使用
在大多數情況下,Prometheus 必須抓取一個端點來檢索指標。以下示例展示瞭如何使用 Express.js 傳送資料
import { PrismaClient } from '@prisma/client'
import express, { Request, Response } from 'express'
const app = express()
const port = 4000
const prisma = new PrismaClient()
app.get('/metrics', async (_req, res: Response) => {
const metrics = await prisma.$metrics.prometheus()
res.end(metrics)
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
以下示例展示瞭如何將 Prisma Client 指標與透過 REST API 端點(結合 Express.js)提供的其他 Prometheus 客戶端庫結合使用
import { PrismaClient } from '@prisma/client'
import express, { Request, Response } from 'express'
import prom from 'prom-client'
const app = express()
const port = 4000
const prisma = new PrismaClient()
const register = new prom.Registry()
prom.collectDefaultMetrics({ register })
app.get('/metrics', async (_req, res: Response) => {
const prismaMetrics = await prisma.$metrics.prometheus()
const appMetrics = await register.metrics()
res.end(prismaMetrics + appMetrics)
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
全域性標籤
你可以為指標新增全域性標籤,以幫助你對指標進行分組和區分。每個 Prisma Client 例項都會將其生成的指標新增這些標籤。例如,你可以使用類似 { server: 'us_server1', 'app_version': 'one' } 的標籤按基礎設施區域或伺服器對指標進行分組。
全域性標籤適用於 JSON 和 Prometheus 格式的指標。
例如,要為 JSON 格式的指標新增全域性標籤,請將以下程式碼新增到你的應用程式中
const metrics = prisma.$metrics.json({
globalLabels: { server: 'us_server1', app_version: 'one' },
})
console.log(metrics)
這將以以下格式返回資訊
{
"counters": [
{
"key": "query_total_operations",
"labels": { "server": "us_server1", "app_version": "one" },
"value": 0,
"description": "The total number of operations executed"
},
{
"key": "prisma_datasource_queries_total",
"labels": { "server": "us_server1", "app_version": "one" },
"value": 0,
"description": "The total number of queries executed"
},
...
],
"gauges": [
...
],
"histograms": [
...
]
}