initialize.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* eslint-disable no-console */
  2. /**
  3. * This module initializes the metrics module. It should be imported once
  4. * before any other module to support code instrumentation.
  5. */
  6. const metricsModuleImportStartTime = performance.now()
  7. const APP_NAME = process.env.METRICS_APP_NAME || 'unknown'
  8. const BUILD_VERSION = process.env.BUILD_VERSION
  9. const ENABLE_PROFILE_AGENT = process.env.ENABLE_PROFILE_AGENT === 'true'
  10. const GCP_OPENTELEMETRY = process.env.GCP_OPENTELEMETRY === 'true'
  11. const JAEGER_OPENTELEMETRY = process.env.JAEGER_OPENTELEMETRY === 'true'
  12. console.log('Initializing metrics')
  13. if (GCP_OPENTELEMETRY || JAEGER_OPENTELEMETRY) {
  14. initializeOpenTelemetryInstrumentation()
  15. initializeOpenTelemetryLogging()
  16. }
  17. if (ENABLE_PROFILE_AGENT) {
  18. initializeProfileAgent()
  19. }
  20. initializePrometheus()
  21. initializePromWrapper()
  22. recordProcessStart()
  23. function initializeOpenTelemetryInstrumentation() {
  24. console.log('Starting OpenTelemetry instrumentation')
  25. const opentelemetry = require('@opentelemetry/sdk-node')
  26. const {
  27. getNodeAutoInstrumentations,
  28. } = require('@opentelemetry/auto-instrumentations-node')
  29. const { Resource } = require('@opentelemetry/resources')
  30. const {
  31. SemanticResourceAttributes,
  32. } = require('@opentelemetry/semantic-conventions')
  33. const resource = new Resource({
  34. [SemanticResourceAttributes.SERVICE_NAME]: APP_NAME,
  35. [SemanticResourceAttributes.SERVICE_NAMESPACE]: 'Overleaf',
  36. 'host.type': 'VM',
  37. })
  38. let exporter
  39. if (GCP_OPENTELEMETRY) {
  40. const GCP = require('@google-cloud/opentelemetry-cloud-trace-exporter')
  41. exporter = new GCP.TraceExporter()
  42. } else if (JAEGER_OPENTELEMETRY) {
  43. const {
  44. OTLPTraceExporter,
  45. } = require('@opentelemetry/exporter-trace-otlp-http')
  46. exporter = new OTLPTraceExporter({
  47. url: `http://${process.env.JAEGER_HOST || 'jaeger'}:4318/v1/traces`,
  48. })
  49. } else {
  50. return
  51. }
  52. const sdk = new opentelemetry.NodeSDK({
  53. traceExporter: exporter,
  54. logger: console,
  55. instrumentations: [getNodeAutoInstrumentations()],
  56. resource,
  57. })
  58. sdk.start()
  59. }
  60. function initializeOpenTelemetryLogging() {
  61. const {
  62. diag,
  63. DiagConsoleLogger,
  64. DiagLogLevel,
  65. } = require('@opentelemetry/api')
  66. diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO)
  67. }
  68. function initializeProfileAgent() {
  69. console.log('Starting Google Profile Agent')
  70. const profiler = require('@google-cloud/profiler')
  71. profiler.start({
  72. serviceContext: {
  73. service: APP_NAME,
  74. version: BUILD_VERSION,
  75. },
  76. })
  77. }
  78. function initializePrometheus() {
  79. const os = require('node:os')
  80. const promClient = require('prom-client')
  81. promClient.register.setDefaultLabels({ app: APP_NAME, host: os.hostname() })
  82. promClient.collectDefaultMetrics({ timeout: 5000, prefix: '' })
  83. }
  84. function initializePromWrapper() {
  85. const promWrapper = require('./prom_wrapper')
  86. promWrapper.setupSweeping()
  87. }
  88. function recordProcessStart() {
  89. const metrics = require('.')
  90. metrics.inc('process_startup')
  91. }
  92. module.exports = { metricsModuleImportStartTime }