diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index cb3db4ee8..8130514fd 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -7,7 +7,7 @@ ENV PATH="$VIRTUAL_ENV/bin:$PATH" FROM base as build RUN apk add --update openssl librrd python3-dev libffi-dev gcc g++ musl-dev libxml2-dev libxslt-dev \ - libressl-dev jpeg-dev rrdtool-dev file make gettext freetype-dev \ + libressl-dev jpeg-dev rrdtool-dev file make gettext freetype-dev cairo-dev \ && rm -rf /var/cache/apk/* RUN python3 -m venv $VIRTUAL_ENV WORKDIR /tmp diff --git a/frontend/src/components/layout/Navbar.vue b/frontend/src/components/layout/Navbar.vue index 34629d03c..b042e33b7 100644 --- a/frontend/src/components/layout/Navbar.vue +++ b/frontend/src/components/layout/Navbar.vue @@ -184,9 +184,14 @@ export default { }, { icon: 'mdi-history', - text: this.$gettext('Logs'), + text: this.$gettext('Monitoring'), roles: ['SuperAdmins', 'Resellers', 'DomainAdmins'], children: [ + { + text: this.$gettext('Statistics'), + to: { name: 'Statistics' }, + roles: ['SuperAdmins'] + }, { text: this.$gettext('Audit trail'), to: { name: 'AuditTrail' }, diff --git a/frontend/src/components/tools/TimeSerieChart.vue b/frontend/src/components/tools/TimeSerieChart.vue index 49d9dcff3..7c16b0453 100644 --- a/frontend/src/components/tools/TimeSerieChart.vue +++ b/frontend/src/components/tools/TimeSerieChart.vue @@ -65,7 +65,14 @@ export default { apexchart: VueApexCharts, DateField }, - props: ['domain', 'graphicSet', 'graphicName'], + props: { + domain: { + type: Object, + required: false + }, + graphicSet: String, + graphicName: String + }, computed: { title () { if (this.statistics) { @@ -133,8 +140,10 @@ export default { const args = { graphSet: this.graphicSet, period: this.period, - graphicName: this.graphicName, - searchQuery: this.domain.name + graphicName: this.graphicName + } + if (this.domain) { + args.searchQuery = this.domain.name } if (this.period === 'custom') { args.start = this.start @@ -149,7 +158,7 @@ export default { this.fetchStatistics() }, watch: { - graphicName (newValue) { + graphicName () { this.$set(this.options, 'colors', this.getColors()) } } diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index dfd4cb84f..a91738e8a 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -152,18 +152,27 @@ const routes = [ } }, { - path: '/logs/audit_trail', - name: 'AuditTrail', - component: () => import('../views/logs/AuditTrail.vue'), + path: '/monitoring/statistics', + name: 'Statistics', + component: () => import('../views/monitoring/Statistics.vue'), meta: { requiresAuth: true, allowedRoles: ['SuperAdmins'] } }, { - path: '/logs/messages', + path: '/monitoring/audit_trail', + name: 'AuditTrail', + component: () => import('../views/monitoring/AuditTrail.vue'), + meta: { + requiresAuth: true, + allowedRoles: ['SuperAdmins'] + } + }, + { + path: '/monitoring/messages', name: 'MessageLog', - component: () => import('../views/logs/Messages.vue'), + component: () => import('../views/monitoring/Messages.vue'), meta: { requiresAuth: true, allowedRoles: ['DomainAdmins', 'SuperAdmins'] diff --git a/frontend/src/views/logs/AuditTrail.vue b/frontend/src/views/monitoring/AuditTrail.vue similarity index 100% rename from frontend/src/views/logs/AuditTrail.vue rename to frontend/src/views/monitoring/AuditTrail.vue diff --git a/frontend/src/views/logs/Messages.vue b/frontend/src/views/monitoring/Messages.vue similarity index 100% rename from frontend/src/views/logs/Messages.vue rename to frontend/src/views/monitoring/Messages.vue diff --git a/frontend/src/views/monitoring/Statistics.vue b/frontend/src/views/monitoring/Statistics.vue new file mode 100644 index 000000000..1254604e1 --- /dev/null +++ b/frontend/src/views/monitoring/Statistics.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/modoboa/maillog/api/v2/serializers.py b/modoboa/maillog/api/v2/serializers.py index 3d45c627d..d61601a93 100644 --- a/modoboa/maillog/api/v2/serializers.py +++ b/modoboa/maillog/api/v2/serializers.py @@ -75,3 +75,12 @@ class MaillogSerializer(serializers.ModelSerializer): "size", "status" ) model = models.Maillog + + +class MaillogGlobalParemetersSerializer(serializers.Serializer): + """A serializer for global parameters.""" + + logfile = serializers.CharField(default="/var/log/mail.log") + rrd_rootdir = serializers.CharField(default="/tmp/modoboa") + greylist = serializers.BooleanField(default=False) + enable_domain_limits = serializers.BooleanField(default=False) diff --git a/modoboa/maillog/apps.py b/modoboa/maillog/apps.py index c4f62c1a5..bcb8215d4 100644 --- a/modoboa/maillog/apps.py +++ b/modoboa/maillog/apps.py @@ -1,8 +1,44 @@ """AppConfig for stats.""" -from django.apps import AppConfig +import collections -from .forms import load_settings +from django.apps import AppConfig +from django.utils.translation import gettext, gettext_lazy as _ + + +GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([ + ("general", { + "label": _("General"), + "params": collections.OrderedDict([ + ("logfile", { + "label": _("Path to the log file"), + "help_text": _("Path to log file used to collect statistics") + }), + ("rrd_rootdir", { + "label": _("Directory to store RRD files"), + "help_text": _("Path to directory where RRD files are stored") + }), + ("greylist", { + "label": _("Show greylisted messages"), + "help_text": _("Differentiate between hard and soft rejects (greylisting)") + }) + ]) + }) +]) + + +def load_maillog_settings(): + """Load app settings.""" + from modoboa.maillog import forms + from modoboa.maillog.api.v2 import serializers + from modoboa.parameters import tools as param_tools + + param_tools.registry.add( + "global", forms.ParametersForm, gettext("Statistics")) + param_tools.registry.add2( + "global", "maillog", gettext("Statistics"), GLOBAL_PARAMETERS_STRUCT, + serializers.MaillogGlobalParemetersSerializer + ) class MaillogConfig(AppConfig): @@ -12,5 +48,5 @@ class MaillogConfig(AppConfig): verbose_name = "Modoboa graphical statistics" def ready(self): - load_settings() + load_maillog_settings() from . import handlers diff --git a/modoboa/maillog/forms.py b/modoboa/maillog/forms.py index 240546199..a7f386d05 100644 --- a/modoboa/maillog/forms.py +++ b/modoboa/maillog/forms.py @@ -49,11 +49,3 @@ class ParametersForm(param_forms.AdminParametersForm): test_mode = getattr(settings, "RRDTOOL_TEST_MODE", False) if rrd_version < required_version and not test_mode: del self.fields["greylist"] - - -def load_settings(): - """Load app settings.""" - from modoboa.parameters import tools as param_tools - - param_tools.registry.add( - "global", ParametersForm, gettext_lazy("Statistics"))