statistics.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import 'reflect-metadata'
  2. import { Logger } from 'winston'
  3. import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch'
  4. import { ContainerConfigLoader } from '../src/Bootstrap/Container'
  5. import TYPES from '../src/Bootstrap/Types'
  6. import { Env } from '../src/Bootstrap/Env'
  7. import { MetricsStoreInterface } from '../src/Domain/Metrics/MetricsStoreInterface'
  8. import { Metric } from '../src/Domain/Metrics/Metric'
  9. import { Time, TimerInterface } from '@standardnotes/time'
  10. const sendStatistics = async (
  11. metricsStore: MetricsStoreInterface,
  12. timer: TimerInterface,
  13. awsRegion: string,
  14. ): Promise<void> => {
  15. const cloudwatchClient = new CloudWatchClient({
  16. region: awsRegion,
  17. })
  18. const minutesToProcess = 30
  19. const metricsToProcess = [Metric.NAMES.ItemCreated, Metric.NAMES.ItemUpdated]
  20. for (const metricToProcess of metricsToProcess) {
  21. for (let i = 0; i <= minutesToProcess; i++) {
  22. const dateNMinutesAgo = timer.getUTCDateNMinutesAgo(minutesToProcess - i)
  23. const timestamp = timer.convertDateToMicroseconds(dateNMinutesAgo)
  24. const statistics = await metricsStore.getStatistics(
  25. metricToProcess,
  26. timestamp,
  27. timestamp + Time.MicrosecondsInAMinute,
  28. )
  29. if (statistics.sampleCount === 0) {
  30. continue
  31. }
  32. await cloudwatchClient.send(
  33. new PutMetricDataCommand({
  34. Namespace: 'SyncingServer',
  35. MetricData: [
  36. {
  37. MetricName: metricToProcess,
  38. Timestamp: dateNMinutesAgo,
  39. StatisticValues: {
  40. Maximum: statistics.max,
  41. Minimum: statistics.min,
  42. SampleCount: statistics.sampleCount,
  43. Sum: statistics.sum,
  44. },
  45. },
  46. ],
  47. }),
  48. )
  49. }
  50. }
  51. const userMetricsToProcess = [Metric.NAMES.ItemOperation, Metric.NAMES.ContentSizeUtilized]
  52. for (const metricToProcess of userMetricsToProcess) {
  53. for (let i = 0; i <= minutesToProcess; i++) {
  54. const dateNMinutesAgo = timer.getUTCDateNMinutesAgo(minutesToProcess - i)
  55. const timestamp = timer.convertDateToMicroseconds(dateNMinutesAgo)
  56. const statistics = await metricsStore.getUserBasedStatistics(metricToProcess, timestamp)
  57. if (statistics.sampleCount === 0) {
  58. continue
  59. }
  60. await cloudwatchClient.send(
  61. new PutMetricDataCommand({
  62. Namespace: 'SyncingServer',
  63. MetricData: [
  64. {
  65. MetricName: metricToProcess,
  66. Timestamp: dateNMinutesAgo,
  67. StatisticValues: {
  68. Maximum: statistics.max,
  69. Minimum: statistics.min,
  70. SampleCount: statistics.sampleCount,
  71. Sum: statistics.sum,
  72. },
  73. },
  74. ],
  75. }),
  76. )
  77. }
  78. }
  79. }
  80. const container = new ContainerConfigLoader('worker')
  81. void container.load().then((container) => {
  82. const env: Env = new Env()
  83. env.load()
  84. const logger: Logger = container.get(TYPES.Sync_Logger)
  85. logger.info('Starting statistics sending')
  86. const metricsStore = container.get<MetricsStoreInterface>(TYPES.Sync_MetricsStore)
  87. const timer = container.get<TimerInterface>(TYPES.Sync_Timer)
  88. const awsRegion = env.get('SNS_AWS_REGION', true)
  89. Promise.resolve(sendStatistics(metricsStore, timer, awsRegion))
  90. .then(() => {
  91. logger.info('Finished statistics sending')
  92. process.exit(0)
  93. })
  94. .catch((error) => {
  95. logger.error('Error while sending statistics', error)
  96. process.exit(1)
  97. })
  98. })