feat(syncing-server): send user based metrics to cloudwatch

This commit is contained in:
Karol Sójko 2024-01-04 17:22:42 +01:00
parent d56410984a
commit 0c3bc0cae6
No known key found for this signature in database
GPG key ID: C2F813669419D05F
4 changed files with 98 additions and 0 deletions

View file

@ -57,6 +57,38 @@ const sendStatistics = async (
) )
} }
} }
const userMetricsToProcess = [Metric.NAMES.ItemOperation, Metric.NAMES.ContentSizeUtilized]
for (const metricToProcess of userMetricsToProcess) {
for (let i = 0; i <= minutesToProcess; i++) {
const dateNMinutesAgo = timer.getUTCDateNMinutesAgo(minutesToProcess - i)
const timestamp = timer.convertDateToMicroseconds(dateNMinutesAgo)
const statistics = await metricsStore.getUserBasedStatistics(metricToProcess, timestamp)
if (statistics.sampleCount === 0) {
continue
}
await cloudwatchClient.send(
new PutMetricDataCommand({
Namespace: 'SyncingServer',
MetricData: [
{
MetricName: metricToProcess,
Timestamp: dateNMinutesAgo,
StatisticValues: {
Maximum: statistics.max,
Minimum: statistics.min,
SampleCount: statistics.sampleCount,
Sum: statistics.sum,
},
},
],
}),
)
}
}
} }
const container = new ContainerConfigLoader('worker') const container = new ContainerConfigLoader('worker')

View file

@ -2,6 +2,15 @@ import { Metric } from './Metric'
export interface MetricsStoreInterface { export interface MetricsStoreInterface {
storeUserBasedMetric(metric: Metric, value: number, userUuid: string): Promise<void> storeUserBasedMetric(metric: Metric, value: number, userUuid: string): Promise<void>
getUserBasedStatistics(
name: string,
timestamp: number,
): Promise<{
sum: number
max: number
min: number
sampleCount: number
}>
storeMetric(metric: Metric): Promise<void> storeMetric(metric: Metric): Promise<void>
getStatistics( getStatistics(
name: string, name: string,

View file

@ -2,6 +2,18 @@ import { MetricsStoreInterface } from '../../Domain/Metrics/MetricsStoreInterfac
import { Metric } from '../../Domain/Metrics/Metric' import { Metric } from '../../Domain/Metrics/Metric'
export class DummyMetricStore implements MetricsStoreInterface { export class DummyMetricStore implements MetricsStoreInterface {
async getUserBasedStatistics(
_name: string,
_timestamp: number,
): Promise<{ sum: number; max: number; min: number; sampleCount: number }> {
return {
sum: 0,
max: 0,
min: 0,
sampleCount: 0,
}
}
async storeUserBasedMetric(_metric: Metric, _value: number, _userUuid: string): Promise<void> { async storeUserBasedMetric(_metric: Metric, _value: number, _userUuid: string): Promise<void> {
// do nothing // do nothing
} }

View file

@ -29,6 +29,51 @@ export class RedisMetricStore implements MetricsStoreInterface {
await pipeline.exec() await pipeline.exec()
} }
async getUserBasedStatistics(
name: string,
timestamp: number,
): Promise<{ sum: number; max: number; min: number; sampleCount: number }> {
const date = this.timer.convertMicrosecondsToDate(timestamp)
const dateToTheMinuteString = this.timer.convertDateToFormattedString(date, 'YYYY-MM-DD HH:mm')
const userMetricsKeys = await this.redisClient.keys(
`${this.METRIC_PER_USER_PREFIX}:*:${name}:${dateToTheMinuteString}`,
)
let sum = 0
let max = 0
let min = 0
let sampleCount = 0
const values = await this.redisClient.mget(userMetricsKeys)
for (const value of values) {
if (!value) {
continue
}
const valueAsNumber = Number(value)
sum += valueAsNumber
sampleCount++
if (valueAsNumber > max) {
max = valueAsNumber
}
if (valueAsNumber < min) {
min = valueAsNumber
}
}
return {
sum,
max,
min,
sampleCount,
}
}
async getStatistics( async getStatistics(
name: string, name: string,
from: number, from: number,