mirror of
https://github.com/OutlineFoundation/outline-server.git
synced 2026-05-13 13:58:57 +00:00
feat(server): use rate() over increase() for bandwidth calculations (#1638)
* feat(server): use `rate()` instead of `increase()` for bandwidth calculations * Add total data transferred a separate top-level metric so we don't have to calculate it client-side.
This commit is contained in:
parent
76a23c6e81
commit
2cc12e0cb3
2 changed files with 37 additions and 29 deletions
|
|
@ -41,7 +41,7 @@ describe('PrometheusManagerMetrics', () => {
|
|||
const managerMetrics = new PrometheusManagerMetrics(
|
||||
new QueryMapPrometheusClient(
|
||||
{
|
||||
'sum(increase(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
'sum(rate(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
resultType: 'vector',
|
||||
result: [
|
||||
{
|
||||
|
|
@ -106,7 +106,7 @@ describe('PrometheusManagerMetrics', () => {
|
|||
},
|
||||
},
|
||||
{
|
||||
'sum(increase(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
'sum(rate(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
resultType: 'matrix',
|
||||
result: [
|
||||
{
|
||||
|
|
@ -162,11 +162,14 @@ describe('PrometheusManagerMetrics', () => {
|
|||
"seconds": 1000
|
||||
},
|
||||
"dataTransferred": {
|
||||
"total": {
|
||||
"bytes": 1000
|
||||
},
|
||||
"bytes": 1000
|
||||
},
|
||||
"bandwidth": {
|
||||
"current": {
|
||||
"bytes": 1234
|
||||
"data": {
|
||||
"bytes": 1234
|
||||
},
|
||||
"timestamp": 1739284734
|
||||
},
|
||||
"peak": {
|
||||
"data": {
|
||||
|
|
@ -216,7 +219,7 @@ describe('PrometheusManagerMetrics', () => {
|
|||
const managerMetrics = new PrometheusManagerMetrics(
|
||||
new QueryMapPrometheusClient(
|
||||
{
|
||||
'sum(increase(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
'sum(rate(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
resultType: 'vector',
|
||||
result: [
|
||||
{
|
||||
|
|
@ -279,7 +282,7 @@ describe('PrometheusManagerMetrics', () => {
|
|||
},
|
||||
},
|
||||
{
|
||||
'sum(increase(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
'sum(rate(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[300s]))': {
|
||||
resultType: 'matrix',
|
||||
result: [
|
||||
{
|
||||
|
|
@ -335,11 +338,14 @@ describe('PrometheusManagerMetrics', () => {
|
|||
"seconds": 1000
|
||||
},
|
||||
"dataTransferred": {
|
||||
"total": {
|
||||
"bytes": 1000
|
||||
},
|
||||
"bytes": 1000
|
||||
},
|
||||
"bandwidth": {
|
||||
"current": {
|
||||
"bytes": 1234
|
||||
"data": {
|
||||
"bytes": 1234
|
||||
},
|
||||
"timestamp": 1739284734
|
||||
},
|
||||
"peak": {
|
||||
"data": {
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ interface ConnectionStats {
|
|||
}
|
||||
|
||||
interface BandwidthStats {
|
||||
total: Data;
|
||||
current: Data;
|
||||
current: TimedData<Data>;
|
||||
peak: TimedData<Data>;
|
||||
}
|
||||
|
||||
interface ServerMetricsServerEntry {
|
||||
tunnelTime: Duration;
|
||||
dataTransferred: BandwidthStats;
|
||||
dataTransferred: Data;
|
||||
bandwidth: BandwidthStats;
|
||||
locations: ServerMetricsLocationEntry[];
|
||||
}
|
||||
|
||||
|
|
@ -113,8 +113,8 @@ export class PrometheusManagerMetrics implements ManagerMetrics {
|
|||
const start = end - timeframe.seconds;
|
||||
|
||||
const [
|
||||
totalDataTransferred,
|
||||
totalDataTransferredRange,
|
||||
bandwidth,
|
||||
bandwidthRange,
|
||||
dataTransferredByLocation,
|
||||
tunnelTimeByLocation,
|
||||
dataTransferredByAccessKey,
|
||||
|
|
@ -123,10 +123,10 @@ export class PrometheusManagerMetrics implements ManagerMetrics {
|
|||
tunnelTimeByAccessKeyRange,
|
||||
] = await Promise.all([
|
||||
this.prometheusClient.query(
|
||||
`sum(increase(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))`
|
||||
`sum(rate(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))`
|
||||
),
|
||||
this.prometheusClient.queryRange(
|
||||
`sum(increase(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))`,
|
||||
`sum(rate(shadowsocks_data_bytes_per_location{dir=~"c<p|p>t"}[${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s]))`,
|
||||
start,
|
||||
end,
|
||||
`${PROMETHEUS_RANGE_QUERY_STEP_SECONDS}s`
|
||||
|
|
@ -159,25 +159,27 @@ export class PrometheusManagerMetrics implements ManagerMetrics {
|
|||
|
||||
const serverMetrics: ServerMetricsServerEntry = {
|
||||
tunnelTime: {seconds: 0},
|
||||
dataTransferred: {
|
||||
total: {bytes: 0},
|
||||
current: {bytes: 0},
|
||||
dataTransferred: {bytes: 0},
|
||||
bandwidth: {
|
||||
current: {data: {bytes: 0}, timestamp: null},
|
||||
peak: {data: {bytes: 0}, timestamp: null},
|
||||
},
|
||||
locations: [],
|
||||
};
|
||||
for (const result of totalDataTransferred.result) {
|
||||
const bytes = result.value ? parseFloat(result.value[1]) : 0;
|
||||
serverMetrics.dataTransferred.current.bytes = bytes;
|
||||
for (const result of bandwidth.result) {
|
||||
if (result.value) {
|
||||
serverMetrics.bandwidth.current.data.bytes = parseFloat(result.value[1]);
|
||||
serverMetrics.bandwidth.current.timestamp = result.value[0];
|
||||
}
|
||||
break; // There should only be one result.
|
||||
}
|
||||
for (const result of totalDataTransferredRange.result) {
|
||||
for (const result of bandwidthRange.result) {
|
||||
const peakDataTransferred = findPeak(result.values ?? []);
|
||||
if (peakDataTransferred !== null) {
|
||||
const peakValue = parseFloat(peakDataTransferred[1]);
|
||||
if (peakValue > 0) {
|
||||
serverMetrics.dataTransferred.peak.data.bytes = peakValue;
|
||||
serverMetrics.dataTransferred.peak.timestamp = Math.min(now, peakDataTransferred[0]);
|
||||
serverMetrics.bandwidth.peak.data.bytes = peakValue;
|
||||
serverMetrics.bandwidth.peak.timestamp = Math.min(now, peakDataTransferred[0]);
|
||||
}
|
||||
}
|
||||
break; // There should only be one result.
|
||||
|
|
@ -194,7 +196,7 @@ export class PrometheusManagerMetrics implements ManagerMetrics {
|
|||
const entry = getServerMetricsLocationEntry(locationMap, result.metric);
|
||||
const bytes = result.value ? parseFloat(result.value[1]) : 0;
|
||||
entry.dataTransferred.bytes = bytes;
|
||||
serverMetrics.dataTransferred.total.bytes += bytes;
|
||||
serverMetrics.dataTransferred.bytes += bytes;
|
||||
}
|
||||
serverMetrics.locations = Array.from(locationMap.values());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue