You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.6 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. const _ = require('lodash')
  2. const { createApolloFetch } = require('apollo-fetch')
  3. const Bugsnag = require('@bugsnag/js')
  4. const { v4: uuid } = require('uuid')
  5. const os = require('os')
  6. const fs = require('fs-extra')
  7. /* global WIKI */
  8. module.exports = {
  9. enabled: false,
  10. init() {
  11. Bugsnag.start({
  12. apiKey: WIKI.data.telemetry.BUGSNAG_ID,
  13. appType: 'server',
  14. appVersion: WIKI.version,
  15. autoDetectErrors: false,
  16. autoTrackSessions: false,
  17. hostname: _.get(WIKI.config, 'telemetry.clientId', uuid()),
  18. enabledReleaseStages: ['production'],
  19. releaseStage: WIKI.IS_DEBUG ? 'development' : 'production',
  20. projectRoot: WIKI.ROOTPATH,
  21. logger: null,
  22. onError: (report) => {
  23. if (!WIKI.telemetry.enabled) { return false }
  24. }
  25. })
  26. WIKI.telemetry = this
  27. if (_.get(WIKI.config, 'telemetry.isEnabled', false) === true && WIKI.config.offline !== true) {
  28. this.enabled = true
  29. this.sendInstanceEvent('STARTUP')
  30. }
  31. },
  32. sendError(err) {
  33. Bugsnag.notify(err)
  34. },
  35. sendEvent(eventCategory, eventAction, eventLabel) {
  36. // TODO
  37. },
  38. async sendInstanceEvent(eventType) {
  39. if (WIKI.devMode) { return }
  40. try {
  41. const apollo = createApolloFetch({
  42. uri: WIKI.config.graphEndpoint
  43. })
  44. // Platform detection
  45. let platform = 'LINUX'
  46. let isDockerized = false
  47. let osname = `${os.type()} ${os.release()}`
  48. switch (os.platform()) {
  49. case 'win32':
  50. platform = 'WINDOWS'
  51. break
  52. case 'darwin':
  53. platform = 'MACOS'
  54. break
  55. default:
  56. platform = 'LINUX'
  57. isDockerized = await fs.pathExists('/.dockerenv')
  58. if (isDockerized) {
  59. osname = 'Docker'
  60. }
  61. break
  62. }
  63. // DB Version detection
  64. let dbVersion = 'Unknown'
  65. switch (WIKI.config.db.type) {
  66. case 'mariadb':
  67. case 'mysql':
  68. const resultMYSQL = await WIKI.models.knex.raw('SELECT VERSION() as version;')
  69. dbVersion = _.get(resultMYSQL, '[0][0].version', 'Unknown')
  70. break
  71. case 'mssql':
  72. const resultMSSQL = await WIKI.models.knex.raw('SELECT @@VERSION as version;')
  73. dbVersion = _.get(resultMSSQL, '[0].version', 'Unknown')
  74. break
  75. case 'postgres':
  76. dbVersion = _.get(WIKI.models, 'knex.client.version', 'Unknown')
  77. break
  78. case 'sqlite':
  79. dbVersion = _.get(WIKI.models, 'knex.client.driver.VERSION', 'Unknown')
  80. break
  81. }
  82. let arch = os.arch().toUpperCase()
  83. if (['ARM', 'ARM64', 'X32', 'X64'].indexOf(arch) < 0) {
  84. arch = 'OTHER'
  85. }
  86. // Send Event
  87. const respStrings = await apollo({
  88. query: `mutation (
  89. $version: String!
  90. $platform: TelemetryPlatform!
  91. $os: String!
  92. $architecture: TelemetryArchitecture!
  93. $dbType: TelemetryDBType!
  94. $dbVersion: String!
  95. $nodeVersion: String!
  96. $cpuCores: Int!
  97. $ramMBytes: Int!,
  98. $clientId: String!,
  99. $event: TelemetryInstanceEvent!
  100. ) {
  101. telemetry {
  102. instance(
  103. version: $version
  104. platform: $platform
  105. os: $os
  106. architecture: $architecture
  107. dbType: $dbType
  108. dbVersion: $dbVersion
  109. nodeVersion: $nodeVersion
  110. cpuCores: $cpuCores
  111. ramMBytes: $ramMBytes
  112. clientId: $clientId
  113. event: $event
  114. ) {
  115. responseResult {
  116. succeeded
  117. errorCode
  118. slug
  119. message
  120. }
  121. }
  122. }
  123. }`,
  124. variables: {
  125. version: WIKI.version,
  126. platform,
  127. os: osname,
  128. architecture: arch,
  129. dbType: WIKI.config.db.type.toUpperCase(),
  130. dbVersion,
  131. nodeVersion: process.version.substr(1),
  132. cpuCores: os.cpus().length,
  133. ramMBytes: Math.round(os.totalmem() / 1024 / 1024),
  134. clientId: WIKI.config.telemetry.clientId,
  135. event: eventType
  136. }
  137. })
  138. const telemetryResponse = _.get(respStrings, 'data.telemetry.instance.responseResult', { succeeded: false, message: 'Unexpected Error' })
  139. if (!telemetryResponse.succeeded) {
  140. WIKI.logger.warn('Failed to send instance telemetry: ' + telemetryResponse.message)
  141. } else {
  142. WIKI.logger.info('Telemetry is active: [ OK ]')
  143. }
  144. } catch (err) {
  145. WIKI.logger.warn(err)
  146. }
  147. },
  148. generateClientId() {
  149. _.set(WIKI.config, 'telemetry.clientId', uuid())
  150. return WIKI.config.telemetry.clientId
  151. }
  152. }