log enums
This commit is contained in:
@@ -19,7 +19,7 @@ from packaging import version as pyver
|
||||
from core.models import TZ_CHOICES
|
||||
from core.utils import get_core_settings
|
||||
from logs.models import BaseAuditModel, DebugLog
|
||||
from tacticalrmm.constants import ONLINE_AGENTS, CheckType, CheckStatus
|
||||
from tacticalrmm.constants import ONLINE_AGENTS, CheckType, CheckStatus, DebugLogType
|
||||
from tacticalrmm.models import PermissionQuerySet
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -723,7 +723,7 @@ class Agent(BaseAuditModel):
|
||||
return tasks
|
||||
|
||||
def _do_nats_debug(self, agent: "Agent", message: str) -> None:
|
||||
DebugLog.error(agent=agent, log_type="agent_issues", message=message)
|
||||
DebugLog.error(agent=agent, log_type=DebugLogType.AGENT_ISSUES, message=message)
|
||||
|
||||
async def nats_cmd(
|
||||
self, data: Dict[Any, Any], timeout: int = 30, wait: bool = True
|
||||
|
||||
@@ -14,7 +14,7 @@ from core.utils import get_core_settings
|
||||
from logs.models import DebugLog, PendingAction
|
||||
from scripts.models import Script
|
||||
from tacticalrmm.celery import app
|
||||
from tacticalrmm.constants import PAAction, PAStatus, CheckStatus
|
||||
from tacticalrmm.constants import PAAction, PAStatus, CheckStatus, DebugLogType
|
||||
|
||||
|
||||
def agent_update(agent_id: str, force: bool = False) -> str:
|
||||
@@ -28,7 +28,7 @@ def agent_update(agent_id: str, force: bool = False) -> str:
|
||||
if agent.arch is None:
|
||||
DebugLog.warning(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"Unable to determine arch on {agent.hostname}({agent.agent_id}). Skipping agent update.",
|
||||
)
|
||||
return "noarch"
|
||||
@@ -236,7 +236,7 @@ def run_script_email_results_task(
|
||||
if r == "timeout":
|
||||
DebugLog.error(
|
||||
agent=agent,
|
||||
log_type="scripting",
|
||||
log_type=DebugLogType.SCRIPTING,
|
||||
message=f"{agent.hostname}({agent.pk}) timed out running script.",
|
||||
)
|
||||
return
|
||||
|
||||
@@ -9,7 +9,7 @@ from django.db.models.fields import BooleanField, PositiveIntegerField
|
||||
from django.utils import timezone as djangotime
|
||||
|
||||
from logs.models import BaseAuditModel, DebugLog
|
||||
from tacticalrmm.constants import CheckType
|
||||
from tacticalrmm.constants import CheckType, DebugLogType
|
||||
from tacticalrmm.models import PermissionQuerySet
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -484,7 +484,7 @@ class Alert(models.Model):
|
||||
else:
|
||||
DebugLog.error(
|
||||
agent=agent,
|
||||
log_type="scripting",
|
||||
log_type=DebugLogType.SCRIPTING,
|
||||
message=f"Failure action: {alert_template.action.name} failed to run on any agent for {agent.hostname}({agent.pk}) failure alert",
|
||||
)
|
||||
|
||||
@@ -608,7 +608,7 @@ class Alert(models.Model):
|
||||
else:
|
||||
DebugLog.error(
|
||||
agent=agent,
|
||||
log_type="scripting",
|
||||
log_type=DebugLogType.SCRIPTING,
|
||||
message=f"Resolved action: {alert_template.action.name} failed to run on any agent for {agent.hostname}({agent.pk}) resolved alert",
|
||||
)
|
||||
|
||||
@@ -635,7 +635,7 @@ class Alert(models.Model):
|
||||
try:
|
||||
temp_args.append(re.sub("\\{\\{.*\\}\\}", value, arg))
|
||||
except Exception as e:
|
||||
DebugLog.error(log_type="scripting", message=str(e))
|
||||
DebugLog.error(log_type=DebugLogType.SCRIPTING, message=str(e))
|
||||
continue
|
||||
|
||||
else:
|
||||
|
||||
@@ -31,6 +31,7 @@ from tacticalrmm.constants import (
|
||||
CheckStatus,
|
||||
AuditObjType,
|
||||
AuditActionType,
|
||||
DebugLogType,
|
||||
)
|
||||
from tacticalrmm.helpers import notify_error
|
||||
from tacticalrmm.utils import reload_nats
|
||||
@@ -99,7 +100,7 @@ class WinUpdates(APIView):
|
||||
asyncio.run(agent.nats_cmd({"func": "rebootnow"}, wait=False))
|
||||
DebugLog.info(
|
||||
agent=agent,
|
||||
log_type="windows_updates",
|
||||
log_type=DebugLogType.WIN_UPDATES,
|
||||
message=f"{agent.hostname} is rebooting after updates were installed.",
|
||||
)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ from logs.models import BaseAuditModel, DebugLog
|
||||
from tacticalrmm.constants import (
|
||||
FIELDS_TRIGGER_TASK_UPDATE_AGENT,
|
||||
POLICY_TASK_FIELDS_TO_COPY,
|
||||
DebugLogType,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -367,7 +368,7 @@ class AutomatedTask(BaseAuditModel):
|
||||
task_result.save(update_fields=["sync_status"])
|
||||
DebugLog.warning(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"Unable to create scheduled task {self.name} on {task_result.agent.hostname}. It will be created when the agent checks in.",
|
||||
)
|
||||
return "timeout"
|
||||
@@ -376,7 +377,7 @@ class AutomatedTask(BaseAuditModel):
|
||||
task_result.save(update_fields=["sync_status"])
|
||||
DebugLog.info(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"{task_result.agent.hostname} task {self.name} was successfully created",
|
||||
)
|
||||
|
||||
@@ -406,7 +407,7 @@ class AutomatedTask(BaseAuditModel):
|
||||
task_result.save(update_fields=["sync_status"])
|
||||
DebugLog.warning(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"Unable to modify scheduled task {self.name} on {task_result.agent.hostname}({task_result.agent.agent_id}). It will try again on next agent checkin",
|
||||
)
|
||||
return "timeout"
|
||||
@@ -415,7 +416,7 @@ class AutomatedTask(BaseAuditModel):
|
||||
task_result.save(update_fields=["sync_status"])
|
||||
DebugLog.info(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"{task_result.agent.hostname} task {self.name} was successfully modified",
|
||||
)
|
||||
|
||||
@@ -449,7 +450,7 @@ class AutomatedTask(BaseAuditModel):
|
||||
|
||||
DebugLog.warning(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"{task_result.agent.hostname} task {self.name} will be deleted on next checkin",
|
||||
)
|
||||
return "timeout"
|
||||
@@ -457,7 +458,7 @@ class AutomatedTask(BaseAuditModel):
|
||||
self.delete()
|
||||
DebugLog.info(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"{task_result.agent.hostname}({task_result.agent.agent_id}) task {self.name} was deleted",
|
||||
)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from alerts.models import Alert
|
||||
from autotasks.models import AutomatedTask, TaskResult
|
||||
from logs.models import DebugLog
|
||||
from tacticalrmm.celery import app
|
||||
from tacticalrmm.constants import DebugLogType
|
||||
|
||||
|
||||
@app.task
|
||||
@@ -83,7 +84,7 @@ def remove_orphaned_win_tasks() -> None:
|
||||
if not isinstance(r, list): # empty list
|
||||
DebugLog.error(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"Unable to pull list of scheduled tasks on {agent.hostname}: {r}",
|
||||
)
|
||||
return
|
||||
@@ -114,13 +115,13 @@ def remove_orphaned_win_tasks() -> None:
|
||||
if ret != "ok":
|
||||
DebugLog.error(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"Unable to clean up orphaned task {task} on {agent.hostname}: {ret}",
|
||||
)
|
||||
else:
|
||||
DebugLog.info(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"Removed orphaned task {task} from {agent.hostname}",
|
||||
)
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ from django.db import models
|
||||
from twilio.base.exceptions import TwilioRestException
|
||||
from twilio.rest import Client as TwClient
|
||||
|
||||
from logs.models import LOG_LEVEL_CHOICES, BaseAuditModel, DebugLog
|
||||
from tacticalrmm.constants import CORESETTINGS_CACHE_KEY
|
||||
from logs.models import BaseAuditModel, DebugLog
|
||||
from tacticalrmm.constants import CORESETTINGS_CACHE_KEY, DebugLogLevel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from alerts.models import AlertTemplate
|
||||
@@ -57,7 +57,7 @@ class CoreSettings(BaseAuditModel):
|
||||
debug_log_prune_days = models.PositiveIntegerField(default=30)
|
||||
audit_log_prune_days = models.PositiveIntegerField(default=0)
|
||||
agent_debug_level = models.CharField(
|
||||
max_length=20, choices=LOG_LEVEL_CHOICES, default="info"
|
||||
max_length=20, choices=DebugLogLevel.choices, default=DebugLogLevel.INFO
|
||||
)
|
||||
clear_faults_days = models.IntegerField(default=0)
|
||||
mesh_token = models.CharField(max_length=255, null=True, blank=True, default="")
|
||||
|
||||
@@ -4,7 +4,14 @@ from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union, cast
|
||||
from django.db import models
|
||||
|
||||
from core.utils import get_core_settings
|
||||
from tacticalrmm.constants import PAAction, PAStatus, AuditActionType, AuditObjType
|
||||
from tacticalrmm.constants import (
|
||||
PAAction,
|
||||
PAStatus,
|
||||
AuditActionType,
|
||||
AuditObjType,
|
||||
DebugLogLevel,
|
||||
DebugLogType,
|
||||
)
|
||||
from tacticalrmm.middleware import get_debug_info, get_username
|
||||
from tacticalrmm.models import PermissionQuerySet
|
||||
|
||||
@@ -249,22 +256,6 @@ class AuditLog(models.Model):
|
||||
)
|
||||
|
||||
|
||||
LOG_LEVEL_CHOICES = [
|
||||
("info", "Info"),
|
||||
("warning", "Warning"),
|
||||
("error", "Error"),
|
||||
("critical", "Critical"),
|
||||
]
|
||||
|
||||
LOG_TYPE_CHOICES = [
|
||||
("agent_update", "Agent Update"),
|
||||
("agent_issues", "Agent Issues"),
|
||||
("win_updates", "Windows Updates"),
|
||||
("system_issues", "System Issues"),
|
||||
("scripting", "Scripting"),
|
||||
]
|
||||
|
||||
|
||||
class DebugLog(models.Model):
|
||||
objects = PermissionQuerySet.as_manager()
|
||||
|
||||
@@ -277,10 +268,10 @@ class DebugLog(models.Model):
|
||||
blank=True,
|
||||
)
|
||||
log_level = models.CharField(
|
||||
max_length=50, choices=LOG_LEVEL_CHOICES, default="info"
|
||||
max_length=50, choices=DebugLogLevel.choices, default=DebugLogLevel.INFO
|
||||
)
|
||||
log_type = models.CharField(
|
||||
max_length=50, choices=LOG_TYPE_CHOICES, default="system_issues"
|
||||
max_length=50, choices=DebugLogType.choices, default=DebugLogType.SYSTEM_ISSUES
|
||||
)
|
||||
message = models.TextField(null=True, blank=True)
|
||||
|
||||
@@ -289,11 +280,14 @@ class DebugLog(models.Model):
|
||||
cls,
|
||||
message: str,
|
||||
agent: "Optional[Agent]" = None,
|
||||
log_type: str = "system_issues",
|
||||
log_type: str = DebugLogType.SYSTEM_ISSUES,
|
||||
) -> None:
|
||||
if get_debug_level() in ["info"]:
|
||||
if get_debug_level() in [DebugLogLevel.INFO]:
|
||||
cls.objects.create(
|
||||
log_level="info", agent=agent, log_type=log_type, message=message
|
||||
log_level=DebugLogLevel.INFO,
|
||||
agent=agent,
|
||||
log_type=log_type,
|
||||
message=message,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -301,11 +295,14 @@ class DebugLog(models.Model):
|
||||
cls,
|
||||
message: str,
|
||||
agent: "Optional[Agent]" = None,
|
||||
log_type: str = "system_issues",
|
||||
log_type: str = DebugLogType.SYSTEM_ISSUES,
|
||||
) -> None:
|
||||
if get_debug_level() in ["info", "warning"]:
|
||||
if get_debug_level() in [DebugLogLevel.INFO, DebugLogLevel.WARN]:
|
||||
cls.objects.create(
|
||||
log_level="warning", agent=agent, log_type=log_type, message=message
|
||||
log_level=DebugLogLevel.INFO,
|
||||
agent=agent,
|
||||
log_type=log_type,
|
||||
message=message,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -313,11 +310,18 @@ class DebugLog(models.Model):
|
||||
cls,
|
||||
message: str,
|
||||
agent: "Optional[Agent]" = None,
|
||||
log_type: str = "system_issues",
|
||||
log_type: str = DebugLogType.SYSTEM_ISSUES,
|
||||
) -> None:
|
||||
if get_debug_level() in ["info", "warning", "error"]:
|
||||
if get_debug_level() in [
|
||||
DebugLogLevel.INFO,
|
||||
DebugLogLevel.WARN,
|
||||
DebugLogLevel.ERROR,
|
||||
]:
|
||||
cls.objects.create(
|
||||
log_level="error", agent=agent, log_type=log_type, message=message
|
||||
log_level=DebugLogLevel.ERROR,
|
||||
agent=agent,
|
||||
log_type=log_type,
|
||||
message=message,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -325,11 +329,19 @@ class DebugLog(models.Model):
|
||||
cls,
|
||||
message: str,
|
||||
agent: "Optional[Agent]" = None,
|
||||
log_type: str = "system_issues",
|
||||
log_type: str = DebugLogType.SYSTEM_ISSUES,
|
||||
) -> None:
|
||||
if get_debug_level() in ["info", "warning", "error", "critical"]:
|
||||
if get_debug_level() in [
|
||||
DebugLogLevel.INFO,
|
||||
DebugLogLevel.WARN,
|
||||
DebugLogLevel.ERROR,
|
||||
DebugLogLevel.CRITICAL,
|
||||
]:
|
||||
cls.objects.create(
|
||||
log_level="critical", agent=agent, log_type=log_type, message=message
|
||||
log_level=DebugLogLevel.CRITICAL,
|
||||
agent=agent,
|
||||
log_type=log_type,
|
||||
message=message,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from unittest.mock import patch
|
||||
from django.utils import timezone as djangotime
|
||||
from model_bakery import baker, seq
|
||||
|
||||
from tacticalrmm.constants import PAAction, PAStatus
|
||||
from tacticalrmm.constants import PAAction, PAStatus, DebugLogLevel, DebugLogType
|
||||
from tacticalrmm.test import TacticalTestCase
|
||||
|
||||
base_url = "/logs"
|
||||
@@ -244,16 +244,16 @@ class TestAuditViews(TacticalTestCase):
|
||||
agent = baker.make_recipe("agents.agent")
|
||||
baker.make(
|
||||
"logs.DebugLog",
|
||||
log_level=cycle(["error", "info", "warning", "critical"]),
|
||||
log_type="agent_issues",
|
||||
log_level=cycle([i.value for i in DebugLogLevel]),
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
agent=agent,
|
||||
_quantity=4,
|
||||
)
|
||||
|
||||
logs = baker.make(
|
||||
"logs.DebugLog",
|
||||
log_type="system_issues",
|
||||
log_level=cycle(["error", "info", "warning", "critical"]),
|
||||
log_type=DebugLogType.SYSTEM_ISSUES,
|
||||
log_level=cycle([i.value for i in DebugLogLevel]),
|
||||
_quantity=15,
|
||||
)
|
||||
|
||||
@@ -270,7 +270,10 @@ class TestAuditViews(TacticalTestCase):
|
||||
self.assertEqual(len(resp.data), 1)
|
||||
|
||||
# test time filter with other
|
||||
data = {"logTypeFilter": "system_issues", "logLevelFilter": "error"}
|
||||
data = {
|
||||
"logTypeFilter": DebugLogType.SYSTEM_ISSUES.value,
|
||||
"logLevelFilter": "error",
|
||||
}
|
||||
resp = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(len(resp.data), 4)
|
||||
@@ -325,24 +328,24 @@ class TestAuditViews(TacticalTestCase):
|
||||
agent2 = baker.make_recipe("agents.agent")
|
||||
baker.make(
|
||||
"logs.DebugLog",
|
||||
log_level=cycle(["error", "info", "warning", "critical"]),
|
||||
log_type="agent_issues",
|
||||
log_level=cycle([i.value for i in DebugLogLevel]),
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
agent=agent,
|
||||
_quantity=4,
|
||||
)
|
||||
|
||||
baker.make(
|
||||
"logs.DebugLog",
|
||||
log_level=cycle(["error", "info", "warning", "critical"]),
|
||||
log_type="agent_issues",
|
||||
log_level=cycle([i.value for i in DebugLogLevel]),
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
agent=agent2,
|
||||
_quantity=8,
|
||||
)
|
||||
|
||||
baker.make(
|
||||
"logs.DebugLog",
|
||||
log_type="system_issues",
|
||||
log_level=cycle(["error", "info", "warning", "critical"]),
|
||||
log_type=DebugLogType.SYSTEM_ISSUES,
|
||||
log_level=cycle([i.value for i in DebugLogLevel]),
|
||||
_quantity=15,
|
||||
)
|
||||
|
||||
|
||||
@@ -117,6 +117,21 @@ class AuditObjType(models.TextChoices):
|
||||
CUSTOM_FIELD = "customfield", "Custom Field"
|
||||
|
||||
|
||||
class DebugLogLevel(models.TextChoices):
|
||||
INFO = "info", "Info"
|
||||
WARN = "warning", "Warning"
|
||||
ERROR = "error", "Error"
|
||||
CRITICAL = "critical", "Critical"
|
||||
|
||||
|
||||
class DebugLogType(models.TextChoices):
|
||||
AGENT_UPDATE = "agent_update", "Agent Update"
|
||||
AGENT_ISSUES = "agent_issues", "Agent Issues"
|
||||
WIN_UPDATES = "win_updates", "Windows Updates"
|
||||
SYSTEM_ISSUES = "system_issues", "System Issues"
|
||||
SCRIPTING = "scripting", "Scripting"
|
||||
|
||||
|
||||
# Agent db fields that are not needed for most queries, speeds up query
|
||||
AGENT_DEFER = (
|
||||
"wmi_detail",
|
||||
|
||||
@@ -19,7 +19,14 @@ from agents.models import Agent
|
||||
from core.models import CodeSignToken
|
||||
from core.utils import get_core_settings
|
||||
from logs.models import DebugLog
|
||||
from tacticalrmm.constants import MONTH_DAYS, MONTHS, WEEK_DAYS, WEEKS, ScriptShell
|
||||
from tacticalrmm.constants import (
|
||||
MONTH_DAYS,
|
||||
MONTHS,
|
||||
WEEK_DAYS,
|
||||
WEEKS,
|
||||
ScriptShell,
|
||||
DebugLogType,
|
||||
)
|
||||
from tacticalrmm.helpers import notify_error
|
||||
|
||||
|
||||
@@ -184,7 +191,7 @@ def reload_nats() -> None:
|
||||
except:
|
||||
DebugLog.critical(
|
||||
agent=agent,
|
||||
log_type="agent_issues",
|
||||
log_type=DebugLogType.AGENT_ISSUES,
|
||||
message=f"{agent.hostname} does not have a user account, NATS will not work",
|
||||
)
|
||||
|
||||
@@ -281,7 +288,7 @@ def replace_db_values(
|
||||
return f"'{value}'" if quotes else value
|
||||
else:
|
||||
DebugLog.error(
|
||||
log_type="scripting",
|
||||
log_type=DebugLogType.SCRIPTING,
|
||||
message=f"{agent.hostname} Couldn't lookup value for: {string}. Make sure it exists in CoreSettings > Key Store", # type:ignore
|
||||
)
|
||||
return ""
|
||||
@@ -315,7 +322,7 @@ def replace_db_values(
|
||||
else:
|
||||
# ignore arg since it is invalid
|
||||
DebugLog.error(
|
||||
log_type="scripting",
|
||||
log_type=DebugLogType.SCRIPTING,
|
||||
message=f"{instance} Not enough information to find value for: {string}. Only agent, site, client, and global are supported.",
|
||||
)
|
||||
return ""
|
||||
@@ -357,7 +364,7 @@ def replace_db_values(
|
||||
else:
|
||||
# ignore arg since property is invalid
|
||||
DebugLog.error(
|
||||
log_type="scripting",
|
||||
log_type=DebugLogType.SCRIPTING,
|
||||
message=f"{instance} Couldn't find property on supplied variable: {string}. Make sure it exists as a custom field or a valid agent property",
|
||||
)
|
||||
return ""
|
||||
@@ -367,7 +374,7 @@ def replace_db_values(
|
||||
return value
|
||||
else:
|
||||
DebugLog.error(
|
||||
log_type="scripting",
|
||||
log_type=DebugLogType.SCRIPTING,
|
||||
message=f" {instance}({instance.pk}) Couldn't lookup value for: {string}. Make sure it exists as a custom field or a valid agent property",
|
||||
)
|
||||
return ""
|
||||
|
||||
@@ -9,6 +9,7 @@ from packaging import version as pyver
|
||||
from agents.models import Agent
|
||||
from logs.models import DebugLog
|
||||
from tacticalrmm.celery import app
|
||||
from tacticalrmm.constants import DebugLogType
|
||||
|
||||
|
||||
@app.task
|
||||
@@ -101,7 +102,7 @@ def check_agent_update_schedule_task() -> None:
|
||||
# initiate update on agent asynchronously and don't worry about ret code
|
||||
DebugLog.info(
|
||||
agent=agent,
|
||||
log_type="windows_updates",
|
||||
log_type=DebugLogType.WIN_UPDATES,
|
||||
message=f"Installing windows updates on {agent.hostname}",
|
||||
)
|
||||
nats_data = {
|
||||
|
||||
Reference in New Issue
Block a user