From 8fe411ec0791c305473262d02a9a8a0cd8f3933a Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Sat, 30 Jul 2022 15:56:11 +0200 Subject: [PATCH] Use `@nextcloud/logger` for frontend logging Using the `@nextcloud/logger` allows to log only events with a configured logging level, so unwanted logging events are skipped which at least lead to minor performance improvements. Signed-off-by: Ferdinand Thiessen --- .eslintrc.js | 8 ++++++-- package-lock.json | 13 +++++++------ package.json | 1 + src/Forms.vue | 11 ++++++----- src/FormsSettings.vue | 6 ++++-- src/components/AppNavigationForm.vue | 4 +++- src/components/Questions/AnswerInput.vue | 9 +++++---- src/components/Questions/QuestionDropdown.vue | 3 ++- src/components/Questions/QuestionMultiple.vue | 3 ++- src/components/SidebarTabs/SharingSearchDiv.vue | 5 +++-- src/components/SidebarTabs/SharingSidebarTab.vue | 7 ++++--- src/mixins/QuestionMixin.js | 3 ++- src/mixins/ViewsMixin.js | 9 +++++---- src/utils/Logger.js | 8 ++++++++ src/views/Create.vue | 7 ++++--- src/views/Results.vue | 11 ++++++----- src/views/Submit.vue | 5 +++-- 17 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 src/utils/Logger.js diff --git a/.eslintrc.js b/.eslintrc.js index 4a44f6861..761dc9c85 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,5 +4,9 @@ module.exports = { }, extends: [ '@nextcloud', - ] -} \ No newline at end of file + ], + rules: { + // We are using the @nextcloud/logger + 'no-console': ['error', { allow: undefined }], + }, +} diff --git a/package-lock.json b/package-lock.json index 3c4f48d12..5957d3940 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@nextcloud/event-bus": "^2.1.1", "@nextcloud/initial-state": "^1.2.1", "@nextcloud/l10n": "^1.6.0", + "@nextcloud/logger": "^2.2.1", "@nextcloud/moment": "^1.2.1", "@nextcloud/router": "^2.0.0", "@nextcloud/vue": "^5.3.1", @@ -2178,9 +2179,9 @@ } }, "node_modules/@nextcloud/logger": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@nextcloud/logger/-/logger-2.2.0.tgz", - "integrity": "sha512-gw9UBsFQi1IHa35XzR9SKguwa6SrjXKbKHRYckXM+2gJCfPXhaIRBug9asTaZZMOJqdSzFvEE76Gz3/yJFxONg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@nextcloud/logger/-/logger-2.2.1.tgz", + "integrity": "sha512-MP2/5ZdjDfcTPO5ASfqV5fVU6TYeaa2QOsi2yXBHrmlJ34+HlDdsoVzDGPrbutGCToAuBDSu7nh0WW2aLOp/9A==", "dependencies": { "@nextcloud/auth": "^1.2.2", "core-js": "^3.6.4" @@ -13331,9 +13332,9 @@ } }, "@nextcloud/logger": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@nextcloud/logger/-/logger-2.2.0.tgz", - "integrity": "sha512-gw9UBsFQi1IHa35XzR9SKguwa6SrjXKbKHRYckXM+2gJCfPXhaIRBug9asTaZZMOJqdSzFvEE76Gz3/yJFxONg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@nextcloud/logger/-/logger-2.2.1.tgz", + "integrity": "sha512-MP2/5ZdjDfcTPO5ASfqV5fVU6TYeaa2QOsi2yXBHrmlJ34+HlDdsoVzDGPrbutGCToAuBDSu7nh0WW2aLOp/9A==", "requires": { "@nextcloud/auth": "^1.2.2", "core-js": "^3.6.4" diff --git a/package.json b/package.json index 87de89c85..0826dc25e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@nextcloud/dialogs": "^3.1.4", "@nextcloud/event-bus": "^2.1.1", "@nextcloud/initial-state": "^1.2.1", + "@nextcloud/logger": "^2.2.1", "@nextcloud/l10n": "^1.6.0", "@nextcloud/moment": "^1.2.1", "@nextcloud/router": "^2.0.0", diff --git a/src/Forms.vue b/src/Forms.vue index b50d3a77c..88c882baf 100644 --- a/src/Forms.vue +++ b/src/Forms.vue @@ -107,6 +107,7 @@ import AppNavigationForm from './components/AppNavigationForm.vue' import EmptyContent from './components/EmptyContent.vue' import PermissionTypes from './mixins/PermissionTypes.js' import OcsResponse2Data from './utils/OcsResponse2Data.js' +import logger from './utils/Logger.js' export default { name: 'Forms', @@ -232,8 +233,8 @@ export default { const response = await axios.get(generateOcsUrl('apps/forms/api/v2/forms')) this.forms = OcsResponse2Data(response) } catch (error) { + logger.error('Error while loading owned forms list', { error }) showError(t('forms', 'An error occurred while loading the forms list')) - console.error(error) } // Load shared forms @@ -241,8 +242,8 @@ export default { const response = await axios.get(generateOcsUrl('apps/forms/api/v2/shared_forms')) this.sharedForms = OcsResponse2Data(response) } catch (error) { + logger.error('Error while loading shared forms list', { error }) showError(t('forms', 'An error occurred while loading the forms list')) - console.error(error) } this.loading = false @@ -265,8 +266,8 @@ export default { this.sharedForms.push(form) } } catch (error) { + logger.error(`Form ${hash} not found`, { error }) showError(t('forms', 'Form not found')) - console.error(error) } finally { this.loading = false } @@ -284,8 +285,8 @@ export default { this.$router.push({ name: 'edit', params: { hash: newForm.hash } }) this.mobileCloseNavigation() } catch (error) { + logger.error('Unable to create new form', { error }) showError(t('forms', 'Unable to create a new form')) - console.error(error) } }, @@ -302,8 +303,8 @@ export default { this.$router.push({ name: 'edit', params: { hash: newForm.hash } }) this.mobileCloseNavigation() } catch (error) { + logger.error(`Unable to copy form ${id}`, { error }) showError(t('forms', 'Unable to copy form')) - console.error(error) } }, diff --git a/src/FormsSettings.vue b/src/FormsSettings.vue index 049f81675..8c3cf03be 100644 --- a/src/FormsSettings.vue +++ b/src/FormsSettings.vue @@ -66,6 +66,8 @@ import CheckboxRadioSwitch from '@nextcloud/vue/dist/Components/CheckboxRadioSwi import Multiselect from '@nextcloud/vue/dist/Components/Multiselect' import SettingsSection from '@nextcloud/vue/dist/Components/SettingsSection' +import logger from './utils/Logger.js' + export default { name: 'FormsSettings', @@ -130,7 +132,7 @@ export default { configValue, }) } catch (error) { - console.error(error) + logger.error('Error while saving configuration', { error }) showError(t('forms', 'Error while saving configuration')) await this.reloadAppConfig() } @@ -144,7 +146,7 @@ export default { const resp = await axios.get(generateUrl('apps/forms/config')) this.appConfig = resp.data } catch (error) { - console.error(error) + logger.error('Error while reloading config', { error }) showError(t('forms', 'Error while reloading config')) } }, diff --git a/src/components/AppNavigationForm.vue b/src/components/AppNavigationForm.vue index c3d1b6df7..749d7c17b 100644 --- a/src/components/AppNavigationForm.vue +++ b/src/components/AppNavigationForm.vue @@ -61,6 +61,8 @@ import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem' import axios from '@nextcloud/axios' import moment from '@nextcloud/moment' +import logger from '../utils/Logger.js' + export default { name: 'AppNavigationForm', @@ -155,8 +157,8 @@ export default { await axios.delete(generateOcsUrl('apps/forms/api/v2/form/{id}', { id: this.form.id })) this.$emit('delete', this.form.id) } catch (error) { + logger.error(`Error while deleting ${this.formTitle}`, { error: error.response }) showError(t('forms', 'Error while deleting {title}', { title: this.formTitle })) - console.error(error.response) } finally { this.loading = false } diff --git a/src/components/Questions/AnswerInput.vue b/src/components/Questions/AnswerInput.vue index 7dc97f829..3c4b4445a 100644 --- a/src/components/Questions/AnswerInput.vue +++ b/src/components/Questions/AnswerInput.vue @@ -38,6 +38,7 @@ import Actions from '@nextcloud/vue/dist/Components/Actions' import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import OcsResponse2Data from '../../utils/OcsResponse2Data.js' +import logger from '../../utils/Logger.js' export default { name: 'AnswerInput', @@ -150,14 +151,14 @@ export default { questionId: answer.questionId, text: answer.text, }) - console.debug('Created answer', answer) + logger.debug('Created answer', { answer }) // Was synced once, this is now up to date with the server delete answer.local return Object.assign({}, answer, OcsResponse2Data(response)) } catch (error) { + logger.error('Error while saving answer', { answer, error }) showError(t('forms', 'Error while saving the answer')) - console.error(error) } return answer @@ -180,10 +181,10 @@ export default { text: answer.text, }, }) - console.debug('Updated answer', answer) + logger.debug('Updated answer', { answer }) } catch (error) { + logger.error('Error while saving answer', { answer, error }) showError(t('forms', 'Error while saving the answer')) - console.error(error) } }, }, diff --git a/src/components/Questions/QuestionDropdown.vue b/src/components/Questions/QuestionDropdown.vue index ca21e0ad3..8392ff8ab 100644 --- a/src/components/Questions/QuestionDropdown.vue +++ b/src/components/Questions/QuestionDropdown.vue @@ -90,6 +90,7 @@ import axios from '@nextcloud/axios' import AnswerInput from './AnswerInput.vue' import QuestionMixin from '../../mixins/QuestionMixin.js' import GenRandomId from '../../utils/GenRandomId.js' +import logger from '../../utils/Logger.js' export default { name: 'QuestionDropdown', @@ -285,8 +286,8 @@ export default { // let's not await, deleting in background axios.delete(generateOcsUrl('apps/forms/api/v2/option/{id}', { id: option.id })) .catch(error => { + logger.error('Error while deleting an option', { option, error }) showError(t('forms', 'There was an issue deleting this option')) - console.error(error) // restore option this.restoreOption(option, optionIndex) }) diff --git a/src/components/Questions/QuestionMultiple.vue b/src/components/Questions/QuestionMultiple.vue index aad539564..5a6ba7e0f 100644 --- a/src/components/Questions/QuestionMultiple.vue +++ b/src/components/Questions/QuestionMultiple.vue @@ -97,6 +97,7 @@ import axios from '@nextcloud/axios' import AnswerInput from './AnswerInput.vue' import QuestionMixin from '../../mixins/QuestionMixin.js' import GenRandomId from '../../utils/GenRandomId.js' +import logger from '../../utils/Logger.js' // Implementations docs // https://www.w3.org/TR/2016/WD-wai-aria-practices-1.1-20160317/examples/radio/radio.html @@ -317,8 +318,8 @@ export default { // let's not await, deleting in background axios.delete(generateOcsUrl('apps/forms/api/v2/option/{id}', { id: option.id })) .catch(error => { + logger.error('Error while deleting an option', { error, option }) showError(t('forms', 'There was an issue deleting this option')) - console.error(error) // restore option this.restoreOption(option, optionIndex) }) diff --git a/src/components/SidebarTabs/SharingSearchDiv.vue b/src/components/SidebarTabs/SharingSearchDiv.vue index de3f85b10..4dc5fdef6 100644 --- a/src/components/SidebarTabs/SharingSearchDiv.vue +++ b/src/components/SidebarTabs/SharingSearchDiv.vue @@ -56,6 +56,7 @@ import debounce from 'debounce' import OcsResponse2Data from '../../utils/OcsResponse2Data.js' import ShareTypes from '../../mixins/ShareTypes.js' +import logger from '../../utils/Logger.js' export default { components: { @@ -210,7 +211,7 @@ export default { this.suggestions = exactSuggestions.concat(suggestions) } catch (error) { - console.error('Loading Suggestions failed.', error) + logger.error('Loading Suggestions failed.', { error }) } finally { this.loading = false } @@ -232,7 +233,7 @@ export default { this.recommendations = this.formatSearchResults(OcsResponse2Data(request).exact) } catch (error) { - console.error('Fetching recommendations failed.', error) + logger.error('Fetching recommendations failed.', { error }) } finally { this.loading = false } diff --git a/src/components/SidebarTabs/SharingSidebarTab.vue b/src/components/SidebarTabs/SharingSidebarTab.vue index 388aeaea0..aa328c711 100644 --- a/src/components/SidebarTabs/SharingSidebarTab.vue +++ b/src/components/SidebarTabs/SharingSidebarTab.vue @@ -139,6 +139,7 @@ import SharingShareDiv from './SharingShareDiv.vue' import ShareTypes from '../../mixins/ShareTypes.js' import ShareLinkMixin from '../../mixins/ShareLinkMixin.js' import OcsResponse2Data from '../../utils/OcsResponse2Data.js' +import logger from '../../utils/Logger.js' export default { components: { @@ -201,7 +202,7 @@ export default { this.$emit('add-share', share) } catch (error) { - console.error(error) + logger.error('Error while adding new share', { error, share: newShare }) showError(t('forms', 'There was an error while adding the share')) } finally { this.isLoading = false @@ -222,7 +223,7 @@ export default { this.$emit('add-share', share) } catch (error) { - console.error(error) + logger.error('Error adding public link', { error }) showError(t('forms', 'There was an error while adding the link')) } finally { this.isLoading = false @@ -243,7 +244,7 @@ export default { })) this.$emit('remove-share', share) } catch (error) { - console.error(error) + logger.error('Error while removing share', { error, share }) showError(t('forms', 'There was an error while removing the share')) } finally { this.isLoading = false diff --git a/src/mixins/QuestionMixin.js b/src/mixins/QuestionMixin.js index dad54d31e..2c4b9aa33 100644 --- a/src/mixins/QuestionMixin.js +++ b/src/mixins/QuestionMixin.js @@ -24,6 +24,7 @@ import { generateOcsUrl } from '@nextcloud/router' import { showError } from '@nextcloud/dialogs' import axios from '@nextcloud/axios' +import logger from '../utils/Logger.js' import Question from '../components/Questions/Question.vue' export default { @@ -196,8 +197,8 @@ export default { }, }) } catch (error) { + logger.error('Error while saving question', { error }) showError(t('forms', 'Error while saving question')) - console.error(error) } }, }, diff --git a/src/mixins/ViewsMixin.js b/src/mixins/ViewsMixin.js index a70a09e0a..21d6b7355 100644 --- a/src/mixins/ViewsMixin.js +++ b/src/mixins/ViewsMixin.js @@ -28,6 +28,7 @@ import Vue from 'vue' import CancelableRequest from '../utils/CancelableRequest.js' import OcsResponse2Data from '../utils/OcsResponse2Data.js' +import logger from '../utils/Logger.js' Vue.use(Clipboard) @@ -79,7 +80,7 @@ export default { this.cancelFetchFullForm('New request pending.') // Output after cancelling previous request for logical order. - console.debug('Loading form', id) + logger.debug(`Loading form ${id}`) // Create new cancelable get request const { request, cancel } = CancelableRequest(async function(url, requestOptions) { @@ -94,9 +95,9 @@ export default { this.isLoadingForm = false } catch (error) { if (axios.isCancel(error)) { - console.debug('The request for form', id, 'has been canceled.', error) + logger.debug(`The request for form ${id} has been canceled`, { error }) } else { - console.error(error) + logger.error(`Unexpected error fetching form ${id}`, { error }) this.isLoadingForm = false } } finally { @@ -116,8 +117,8 @@ export default { }, }) } catch (error) { + logger.error('Error saving form property', { error }) showError(t('forms', 'Error while saving form')) - console.error(error) } }, }, diff --git a/src/utils/Logger.js b/src/utils/Logger.js new file mode 100644 index 000000000..a9f7ce74f --- /dev/null +++ b/src/utils/Logger.js @@ -0,0 +1,8 @@ +import { getLoggerBuilder } from '@nextcloud/logger' + +const logger = getLoggerBuilder() + .setApp('forms') + .detectUser() + .build() + +export default logger diff --git a/src/views/Create.vue b/src/views/Create.vue index f7599cbdb..a2249f474 100644 --- a/src/views/Create.vue +++ b/src/views/Create.vue @@ -142,6 +142,7 @@ import QuestionMultiple from '../components/Questions/QuestionMultiple.vue' import QuestionShort from '../components/Questions/QuestionShort.vue' import TopBar from '../components/TopBar.vue' import ViewsMixin from '../mixins/ViewsMixin.js' +import logger from '../utils/Logger.js' import SetWindowTitle from '../utils/SetWindowTitle.js' import OcsResponse2Data from '../utils/OcsResponse2Data.js' @@ -308,7 +309,7 @@ export default { }) } catch (error) { - console.error(error) + logger.error('Error while adding new question', { error }) showError(t('forms', 'There was an error while adding the new question')) } finally { this.isLoadingQuestions = false @@ -329,7 +330,7 @@ export default { const index = this.form.questions.findIndex(search => search.id === id) this.form.questions.splice(index, 1) } catch (error) { - console.error(error) + logger.error(`Error while removing question ${id}`, { error }) showError(t('forms', 'There was an error while removing the question')) } finally { this.isLoadingQuestions = false @@ -349,8 +350,8 @@ export default { newOrder, }) } catch (error) { + logger.error('Error while saving form', { error }) showError(t('forms', 'Error while saving form')) - console.error(error) } finally { this.isLoadingQuestions = false } diff --git a/src/views/Results.vue b/src/views/Results.vue index a445c8877..5020ef178 100644 --- a/src/views/Results.vue +++ b/src/views/Results.vue @@ -138,6 +138,7 @@ import Submission from '../components/Results/Submission.vue' import TopBar from '../components/TopBar.vue' import ViewsMixin from '../mixins/ViewsMixin.js' import answerTypes from '../models/AnswerTypes.js' +import logger from '../utils/Logger.js' import SetWindowTitle from '../utils/SetWindowTitle.js' import OcsResponse2Data from '../utils/OcsResponse2Data.js' @@ -226,7 +227,7 @@ export default { async loadFormResults() { this.loadingResults = true - console.debug('Loading results for form', this.form.hash) + logger.debug(`Loading results for form ${this.form.hash}`) try { const response = await axios.get(generateOcsUrl('apps/forms/api/v2/submissions/{hash}', { hash: this.form.hash })) @@ -240,7 +241,7 @@ export default { this.$set(this.form, 'submissions', loadedSubmissions) this.$set(this.form, 'questions', loadedQuestions) } catch (error) { - console.error(error) + logger.error('Error while loading results', { error }) showError(t('forms', 'There was an error while loading the results')) } finally { this.loadingResults = false @@ -259,7 +260,7 @@ export default { }) showSuccess(t('forms', 'Export successful to {file}', { file: OcsResponse2Data(response) })) } catch (error) { - console.error(error) + logger.error('Error while exporting to Files', { error }) showError(t('forms', 'There was an error, while exporting to Files')) } }) @@ -273,7 +274,7 @@ export default { const index = this.form.submissions.findIndex(search => search.id === id) this.form.submissions.splice(index, 1) } catch (error) { - console.error(error) + logger.error(`Error while removing response ${id}`, { error }) showError(t('forms', 'There was an error while removing this response')) } finally { this.loadingResults = false @@ -290,7 +291,7 @@ export default { await axios.delete(generateOcsUrl('apps/forms/api/v2/submissions/{formId}', { formId: this.form.id })) this.form.submissions = [] } catch (error) { - console.error(error) + logger.error('Error while removing responses', { error }) showError(t('forms', 'There was an error while removing responses')) } finally { this.loadingResults = false diff --git a/src/views/Submit.vue b/src/views/Submit.vue index 9ec8edb9b..5c7ee04e4 100644 --- a/src/views/Submit.vue +++ b/src/views/Submit.vue @@ -83,6 +83,7 @@ import axios from '@nextcloud/axios' import AppContent from '@nextcloud/vue/dist/Components/AppContent' import answerTypes from '../models/AnswerTypes.js' +import logger from '../utils/Logger.js' import EmptyContent from '../components/EmptyContent.vue' import Question from '../components/Questions/Question.vue' @@ -180,7 +181,7 @@ export default { hash() { // If public view, abort. Should normally not occur. if (this.publicView) { - console.error('Hash changed on public View. Aborting.') + logger.error('Hash changed on public View. Aborting.') return } this.resetData() @@ -238,7 +239,7 @@ export default { }) this.success = true } catch (error) { - console.error(error) + logger.error('Error while submitting the form', { error }) showError(t('forms', 'There was an error submitting the form')) } finally { this.loading = false