Browse Source

feat: utilities - telemetry

Nick 6 years ago
parent
commit
1424c3a8bf

+ 90 - 9
client/components/admin/admin-utilities-telemetry.vue

@@ -15,35 +15,35 @@
             v-list-tile-avatar: v-icon info_outline
             v-list-tile-content
               v-list-tile-title.body-1 Version of Wiki.js installed
-              v-list-tile-subtitle.caption: em e.g. v2.0.123
+              v-list-tile-sub-title.caption: em e.g. v2.0.123
           v-list-tile
             v-list-tile-avatar: v-icon info_outline
             v-list-tile-content
               v-list-tile-title.body-1 Basic OS information
-              v-list-tile-subtitle.caption: em Platform (Linux, macOS or Windows), Total CPU cores and DB type (PostgreSQL, MySQL, MariaDB, SQLite or SQL Server)
+              v-list-tile-sub-title.caption: em Platform (Linux, macOS or Windows), Total CPU cores and DB type (PostgreSQL, MySQL, MariaDB, SQLite or SQL Server)
           v-list-tile
             v-list-tile-avatar: v-icon info_outline
             v-list-tile-content
               v-list-tile-title.body-1 Crash debug data
-              v-list-tile-subtitle.caption: em Stack trace of the error
+              v-list-tile-sub-title.caption: em Stack trace of the error
           v-list-tile
             v-list-tile-avatar: v-icon info_outline
             v-list-tile-content
               v-list-tile-title.body-1 Setup analytics
-              v-list-tile-subtitle.caption: em Installation checkpoint reached
+              v-list-tile-sub-title.caption: em Installation checkpoint reached
         .body-1.pl-3 Note that crash debug data is stored for a maximum of 30 days while analytics are stored for a maximum of 16 months, after which it is permanently deleted.
         v-divider.my-3
         v-subheader What is it used for?
         .body-1.pl-3 Telemetry is used by developers to improve Wiki.js, mostly for the following reasons:
         v-list(dense)
           v-list-tile
-            v-list-tile-avatar: v-icon info_outline
+            v-list-tile-avatar: v-icon chevron_right
             v-list-tile-content: v-list-tile-title.body-1 Identify critical bugs more easily and fix them in a timely manner.
           v-list-tile
-            v-list-tile-avatar: v-icon info_outline
+            v-list-tile-avatar: v-icon chevron_right
             v-list-tile-content: v-list-tile-title.body-1 Understand the upgrade rate of current installations.
           v-list-tile
-            v-list-tile-avatar: v-icon info_outline
+            v-list-tile-avatar: v-icon chevron_right
             v-list-tile-content: v-list-tile-title.body-1  Optimize performance and testing scenarios based on most popular environments.
         .body-1.pl-3 Only authorized developers have access to the data. It is not shared to any 3rd party nor is it used for any other application than improving Wiki.js.
         v-divider.my-3
@@ -52,13 +52,12 @@
           v-switch.mt-0(
             v-model='telemetry',
             label='Enable Telemetry',
-            :value='true',
             color='primary',
             hint='Allow Wiki.js to transmit telemetry data.',
             persistent-hint
           )
           .subheading.mt-3.grey--text.text--darken-1 Client ID
-          .body-1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+          .body-1 {{clientId}}
       v-card-chin
         v-btn(depressed, color='success', @click='updateTelemetry')
           v-icon(left) chevron_right
@@ -71,7 +70,89 @@
 </template>
 
 <script>
+import _ from 'lodash'
+
+import utilityTelemetryResetIdMutation from 'gql/admin/utilities/utilities-mutation-telemetry-resetid.gql'
+import utilityTelemetrySetMutation from 'gql/admin/utilities/utilities-mutation-telemetry-set.gql'
+import utilityTelemetryQuery from 'gql/admin/utilities/utilities-query-telemetry.gql'
+
 export default {
+  data() {
+    return {
+      telemetry: false,
+      clientId: 'N/A'
+    }
+  },
+  methods: {
+    async updateTelemetry() {
+      this.loading = true
+      this.$store.commit(`loadingStart`, 'admin-utilities-telemetry-set')
+
+      try {
+        const respRaw = await this.$apollo.mutate({
+          mutation: utilityTelemetrySetMutation,
+          variables: {
+            enabled: this.telemetry
+          }
+        })
+        const resp = _.get(respRaw, 'data.system.setTelemetry.responseResult', {})
+        if (resp.succeeded) {
+          this.$store.commit('showNotification', {
+            message: 'Telemetry updated successfully.',
+            style: 'success',
+            icon: 'check'
+          })
+        } else {
+          throw new Error(resp.message)
+        }
+      } catch (err) {
+        this.$store.commit('pushGraphError', err)
+      }
+
+      this.$store.commit(`loadingStop`, 'admin-utilities-telemetry-set')
+      this.loading = false
+    },
+    async resetClientId() {
+      this.loading = true
+      this.$store.commit(`loadingStart`, 'admin-utilities-telemetry-resetid')
+
+      try {
+        const respRaw = await this.$apollo.mutate({
+          mutation: utilityTelemetryResetIdMutation
+        })
+        const resp = _.get(respRaw, 'data.system.resetTelemetryClientId.responseResult', {})
+        if (resp.succeeded) {
+          this.$apollo.queries.telemetry.refetch()
+          this.$store.commit('showNotification', {
+            message: 'Telemetry Client ID reset successfully.',
+            style: 'success',
+            icon: 'check'
+          })
+        } else {
+          throw new Error(resp.message)
+        }
+      } catch (err) {
+        this.$store.commit('pushGraphError', err)
+      }
+
+      this.$store.commit(`loadingStop`, 'admin-utilities-telemetry-resetid')
+      this.loading = false
+    }
+  },
+  apollo: {
+    telemetry: {
+      query: utilityTelemetryQuery,
+      fetchPolicy: 'network-only',
+      manual: true,
+      result ({ data }) {
+        this.telemetry = _.get(data, 'system.info.telemetry', false)
+        this.clientId = _.get(data, 'system.info.telemetryClientId', 'N/A')
+      },
+      watchLoading (isLoading) {
+        this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-utilities-telemetry-refresh')
+      }
+    }
+  }
 }
 </script>
 

+ 1 - 1
client/components/admin/admin-utilities.vue

@@ -65,7 +65,7 @@ export default {
           key: 'UtilityImportv1',
           icon: 'present_to_all',
           i18nKey: 'importv1',
-          isAvailable: true
+          isAvailable: false
         },
         {
           key: 'UtilityTelemetry',

+ 12 - 0
client/graph/admin/utilities/utilities-mutation-telemetry-resetid.gql

@@ -0,0 +1,12 @@
+mutation {
+  system {
+    resetTelemetryClientId {
+      responseResult {
+        succeeded
+        errorCode
+        slug
+        message
+      }
+    }
+  }
+}

+ 12 - 0
client/graph/admin/utilities/utilities-mutation-telemetry-set.gql

@@ -0,0 +1,12 @@
+mutation($enabled: Boolean!) {
+  system {
+    setTelemetry(enabled: $enabled) {
+      responseResult {
+        succeeded
+        errorCode
+        slug
+        message
+      }
+    }
+  }
+}

+ 8 - 0
client/graph/admin/utilities/utilities-query-telemetry.gql

@@ -0,0 +1,8 @@
+query {
+  system {
+    info {
+      telemetry
+      telemetryClientId
+    }
+  }
+}

+ 38 - 9
server/graph/resolvers/system.js

@@ -43,12 +43,38 @@ module.exports = {
       return {
         responseResult: graphHelper.generateSuccess('System Flags applied successfully')
       }
+    },
+    async resetTelemetryClientId(obj, args, context) {
+      try {
+        WIKI.telemetry.generateClientId()
+        await WIKI.configSvc.saveToDb(['telemetry'])
+        return {
+          responseResult: graphHelper.generateSuccess('Telemetry state updated successfully')
+        }
+      } catch(err) {
+        return graphHelper.generateError(err)
+      }
+    },
+    async setTelemetry(obj, args, context) {
+      try {
+        _.set(WIKI.config, 'telemetry.isEnabled', args.enabled)
+        WIKI.telemetry.enabled = args.enabled
+        await WIKI.configSvc.saveToDb(['telemetry'])
+        return {
+          responseResult: graphHelper.generateSuccess('Telemetry Client ID has been reset successfully')
+        }
+      } catch(err) {
+        return graphHelper.generateError(err)
+      }
     }
   },
   SystemInfo: {
     configFile() {
       return path.join(process.cwd(), 'config.yml')
     },
+    cpuCores() {
+      return os.cpus().length
+    },
     currentVersion() {
       return WIKI.version
     },
@@ -83,12 +109,18 @@ module.exports = {
         return WIKI.config.db.host
       }
     },
+    hostname() {
+      return os.hostname()
+    },
     latestVersion() {
       return WIKI.system.updates.version
     },
     latestVersionReleaseDate() {
       return moment.utc(WIKI.system.updates.releaseDate)
     },
+    nodeVersion() {
+      return process.version.substr(1)
+    },
     async operatingSystem() {
       let osLabel = `${os.type()} (${os.platform()}) ${os.release()} ${os.arch()}`
       if (os.platform() === 'linux') {
@@ -104,21 +136,18 @@ module.exports = {
       }
       return os.platform()
     },
-    hostname() {
-      return os.hostname()
-    },
-    cpuCores() {
-      return os.cpus().length
-    },
     ramTotal() {
       return filesize(os.totalmem())
     },
+    telemetry() {
+      return WIKI.telemetry.enabled
+    },
+    telemetryClientId() {
+      return WIKI.config.telemetry.clientId
+    },
     workingDirectory() {
       return process.cwd()
     },
-    nodeVersion() {
-      return process.version.substr(1)
-    },
     async groupsTotal() {
       const total = await WIKI.models.groups.query().count('* as total').first().pluck('total')
       return _.toSafeInteger(total)

+ 8 - 0
server/graph/schemas/system.graphql

@@ -27,6 +27,12 @@ type SystemMutation {
   updateFlags(
     flags: [SystemFlagInput]!
   ): DefaultResponse @auth(requires: ["manage:system"])
+
+  resetTelemetryClientId: DefaultResponse @auth(requires: ["manage:system"])
+
+  setTelemetry(
+    enabled: Boolean!
+  ): DefaultResponse @auth(requires: ["manage:system"])
 }
 
 # -----------------------------------------------
@@ -59,6 +65,8 @@ type SystemInfo {
   pagesTotal: Int @auth(requires: ["manage:system", "manage:navigation", "manage:pages", "delete:pages"])
   platform: String @auth(requires: ["manage:system"])
   ramTotal: String @auth(requires: ["manage:system"])
+  telemetry: Boolean @auth(requires: ["manage:system"])
+  telemetryClientId: String @auth(requires: ["manage:system"])
   usersTotal: Int @auth(requires: ["manage:system", "manage:navigation", "manage:groups", "write:groups", "manage:users", "write:users"])
   workingDirectory: String @auth(requires: ["manage:system"])
 }