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