فهرست منبع

8984 Allow script log to be filtered (#16446)

* 8984 filter by script log level

* 8984 filter log list

* 8984 add dropdown

* 8984 add dropdown

* 8984 fix button color

* Update netbox/extras/views.py

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* 8984 review changes

* 8984 review changes

* 8984 review changes

* Clean up log threshold selector

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Arthur Hanson 1 سال پیش
والد
کامیت
5ac5135dbc
3فایلهای تغییر یافته به همراه63 افزوده شده و 23 حذف شده
  1. 11 0
      netbox/extras/constants.py
  2. 32 21
      netbox/extras/views.py
  3. 20 2
      netbox/templates/extras/script_result.html

+ 11 - 0
netbox/extras/constants.py

@@ -1,3 +1,5 @@
+from extras.choices import LogLevelChoices
+
 # Events
 # Events
 EVENT_CREATE = 'create'
 EVENT_CREATE = 'create'
 EVENT_UPDATE = 'update'
 EVENT_UPDATE = 'update'
@@ -135,3 +137,12 @@ DEFAULT_DASHBOARD = [
         }
         }
     },
     },
 ]
 ]
+
+LOG_LEVEL_RANK = {
+    LogLevelChoices.LOG_DEFAULT: 0,
+    LogLevelChoices.LOG_DEBUG: 1,
+    LogLevelChoices.LOG_SUCCESS: 2,
+    LogLevelChoices.LOG_INFO: 3,
+    LogLevelChoices.LOG_WARNING: 4,
+    LogLevelChoices.LOG_FAILURE: 5,
+}

+ 32 - 21
netbox/extras/views.py

@@ -14,6 +14,7 @@ from core.forms import ManagedFileForm
 from core.models import Job
 from core.models import Job
 from core.tables import JobTable
 from core.tables import JobTable
 from dcim.models import Device, DeviceRole, Platform
 from dcim.models import Device, DeviceRole, Platform
+from extras.choices import LogLevelChoices
 from extras.dashboard.forms import DashboardWidgetAddForm, DashboardWidgetForm
 from extras.dashboard.forms import DashboardWidgetAddForm, DashboardWidgetForm
 from extras.dashboard.utils import get_widget_class
 from extras.dashboard.utils import get_widget_class
 from netbox.constants import DEFAULT_ACTION_PERMISSIONS
 from netbox.constants import DEFAULT_ACTION_PERMISSIONS
@@ -30,6 +31,7 @@ from utilities.templatetags.builtins.filters import render_markdown
 from utilities.views import ContentTypePermissionRequiredMixin, get_viewname, register_model_view
 from utilities.views import ContentTypePermissionRequiredMixin, get_viewname, register_model_view
 from virtualization.models import VirtualMachine
 from virtualization.models import VirtualMachine
 from . import filtersets, forms, tables
 from . import filtersets, forms, tables
+from .constants import LOG_LEVEL_RANK
 from .models import *
 from .models import *
 from .scripts import run_script
 from .scripts import run_script
 from .tables import ReportResultsTable, ScriptResultsTable
 from .tables import ReportResultsTable, ScriptResultsTable
@@ -1119,22 +1121,27 @@ class ScriptResultView(TableMixin, generic.ObjectView):
         tests = None
         tests = None
         table = None
         table = None
         index = 0
         index = 0
+
+        log_threshold = LOG_LEVEL_RANK.get(request.GET.get('log_threshold', LogLevelChoices.LOG_DEFAULT))
         if job.data:
         if job.data:
+
             if 'log' in job.data:
             if 'log' in job.data:
                 if 'tests' in job.data:
                 if 'tests' in job.data:
                     tests = job.data['tests']
                     tests = job.data['tests']
 
 
                 for log in job.data['log']:
                 for log in job.data['log']:
-                    index += 1
-                    result = {
-                        'index': index,
-                        'time': log.get('time'),
-                        'status': log.get('status'),
-                        'message': log.get('message'),
-                        'object': log.get('obj'),
-                        'url': log.get('url'),
-                    }
-                    data.append(result)
+                    log_level = LOG_LEVEL_RANK.get(log.get('status'), LogLevelChoices.LOG_DEFAULT)
+                    if log_level >= log_threshold:
+                        index += 1
+                        result = {
+                            'index': index,
+                            'time': log.get('time'),
+                            'status': log.get('status'),
+                            'message': log.get('message'),
+                            'object': log.get('obj'),
+                            'url': log.get('url'),
+                        }
+                        data.append(result)
 
 
                 table = ScriptResultsTable(data, user=request.user)
                 table = ScriptResultsTable(data, user=request.user)
                 table.configure(request)
                 table.configure(request)
@@ -1146,17 +1153,19 @@ class ScriptResultView(TableMixin, generic.ObjectView):
             for method, test_data in tests.items():
             for method, test_data in tests.items():
                 if 'log' in test_data:
                 if 'log' in test_data:
                     for time, status, obj, url, message in test_data['log']:
                     for time, status, obj, url, message in test_data['log']:
-                        index += 1
-                        result = {
-                            'index': index,
-                            'method': method,
-                            'time': time,
-                            'status': status,
-                            'object': obj,
-                            'url': url,
-                            'message': message,
-                        }
-                        data.append(result)
+                        log_level = LOG_LEVEL_RANK.get(status, LogLevelChoices.LOG_DEFAULT)
+                        if log_level >= log_threshold:
+                            index += 1
+                            result = {
+                                'index': index,
+                                'method': method,
+                                'time': time,
+                                'status': status,
+                                'object': obj,
+                                'url': url,
+                                'message': message,
+                            }
+                            data.append(result)
 
 
             table = ReportResultsTable(data, user=request.user)
             table = ReportResultsTable(data, user=request.user)
             table.configure(request)
             table.configure(request)
@@ -1174,6 +1183,8 @@ class ScriptResultView(TableMixin, generic.ObjectView):
             'script': job.object,
             'script': job.object,
             'job': job,
             'job': job,
             'table': table,
             'table': table,
+            'log_levels': dict(LogLevelChoices),
+            'log_threshold': request.GET.get('log_threshold', LogLevelChoices.LOG_DEFAULT)
         }
         }
 
 
         if job.data and 'log' in job.data:
         if job.data and 'log' in job.data:

+ 20 - 2
netbox/templates/extras/script_result.html

@@ -42,8 +42,26 @@
     <div class="tab-pane show active" id="results" role="tabpanel" aria-labelledby="results-tab">
     <div class="tab-pane show active" id="results" role="tabpanel" aria-labelledby="results-tab">
 
 
       {# Object table controls #}
       {# Object table controls #}
-      <div class="row mb-3">
-        <div class="col-auto ms-auto d-print-none">
+      <div class="d-flex align-items-center mb-3">
+        <div>{% trans "Log threshold" %}</div>
+
+        <div class="px-2 d-print-none">
+          <div class="dropdown">
+            <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
+              {{ log_levels|get_key:log_threshold }}
+            </button>
+            <div class="dropdown-menu">
+              {% for level, name in log_levels.items %}
+                <a class="dropdown-item d-flex justify-content-between" href="{% url 'extras:script_result' job_pk=job.pk %}?log_threshold={{ level }}">
+                  {{ name }}
+                  {% if level == log_threshold %}<span class="badge bg-green ms-auto"></span>{% endif %}
+                </a>
+              {% endfor %}
+            </div>
+          </div>
+        </div>
+
+        <div class="ms-auto d-print-none">
           {% if request.user.is_authenticated and job.completed %}
           {% if request.user.is_authenticated and job.completed %}
             <div class="table-configure input-group">
             <div class="table-configure input-group">
               <button type="button" data-bs-toggle="modal" title="{% trans "Configure Table" %}" data-bs-target="#ObjectTable_config"
               <button type="button" data-bs-toggle="modal" title="{% trans "Configure Table" %}" data-bs-target="#ObjectTable_config"