139 lines
4.9 KiB
Python
139 lines
4.9 KiB
Python
from django.core.management.base import BaseCommand, CommandError
|
|
from django.utils import timezone
|
|
from datetime import timedelta
|
|
from incident_intelligence.models import Incident
|
|
from knowledge_learning.services.recommendation_engine import RecommendationEngine
|
|
from knowledge_learning.models import IncidentRecommendation
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Generate recommendations for incidents'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
'--days',
|
|
type=int,
|
|
default=1,
|
|
help='Number of days back to look for incidents (default: 1)'
|
|
)
|
|
parser.add_argument(
|
|
'--status',
|
|
type=str,
|
|
choices=['OPEN', 'IN_PROGRESS', 'RESOLVED', 'CLOSED'],
|
|
default='OPEN',
|
|
help='Only generate recommendations for incidents with specific status (default: OPEN)'
|
|
)
|
|
parser.add_argument(
|
|
'--severity',
|
|
type=str,
|
|
choices=['LOW', 'MEDIUM', 'HIGH', 'CRITICAL', 'EMERGENCY'],
|
|
help='Only generate recommendations for incidents with specific severity'
|
|
)
|
|
parser.add_argument(
|
|
'--force',
|
|
action='store_true',
|
|
help='Force generation even if recommendations already exist'
|
|
)
|
|
parser.add_argument(
|
|
'--dry-run',
|
|
action='store_true',
|
|
help='Show what would be generated without actually creating recommendations'
|
|
)
|
|
parser.add_argument(
|
|
'--max-recommendations',
|
|
type=int,
|
|
default=5,
|
|
help='Maximum number of recommendations per incident (default: 5)'
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
days = options['days']
|
|
status = options['status']
|
|
severity = options['severity']
|
|
force = options['force']
|
|
dry_run = options['dry_run']
|
|
max_recommendations = options['max_recommendations']
|
|
|
|
# Calculate date range
|
|
end_date = timezone.now()
|
|
start_date = end_date - timedelta(days=days)
|
|
|
|
self.stdout.write(
|
|
self.style.SUCCESS(f'Looking for {status} incidents from {start_date.date()} to {end_date.date()}')
|
|
)
|
|
|
|
# Build queryset for incidents
|
|
queryset = Incident.objects.filter(
|
|
status=status,
|
|
created_at__gte=start_date,
|
|
created_at__lte=end_date
|
|
)
|
|
|
|
if severity:
|
|
queryset = queryset.filter(severity=severity)
|
|
|
|
# Filter out incidents that already have recommendations (unless force is used)
|
|
if not force:
|
|
existing_recommendation_incidents = IncidentRecommendation.objects.values_list('incident_id', flat=True)
|
|
queryset = queryset.exclude(id__in=existing_recommendation_incidents)
|
|
|
|
incidents = list(queryset)
|
|
|
|
if not incidents:
|
|
self.stdout.write(
|
|
self.style.WARNING('No incidents found matching criteria')
|
|
)
|
|
return
|
|
|
|
self.stdout.write(
|
|
self.style.SUCCESS(f'Found {len(incidents)} incidents to process')
|
|
)
|
|
|
|
if dry_run:
|
|
self.stdout.write(self.style.WARNING('DRY RUN - No recommendations will be created'))
|
|
for incident in incidents:
|
|
self.stdout.write(f' - {incident.title} ({incident.severity}) - {incident.created_at}')
|
|
return
|
|
|
|
# Initialize recommendation engine
|
|
recommendation_engine = RecommendationEngine()
|
|
|
|
success_count = 0
|
|
error_count = 0
|
|
total_recommendations = 0
|
|
|
|
for incident in incidents:
|
|
try:
|
|
self.stdout.write(f'Generating recommendations for: {incident.title}')
|
|
|
|
recommendations = recommendation_engine.generate_recommendations(
|
|
incident_id=str(incident.id),
|
|
max_recommendations=max_recommendations,
|
|
min_confidence=0.5
|
|
)
|
|
|
|
self.stdout.write(
|
|
self.style.SUCCESS(f' ✓ Generated {len(recommendations)} recommendations')
|
|
)
|
|
success_count += 1
|
|
total_recommendations += len(recommendations)
|
|
|
|
except Exception as e:
|
|
self.stdout.write(
|
|
self.style.ERROR(f' ✗ Failed to generate recommendations: {str(e)}')
|
|
)
|
|
error_count += 1
|
|
|
|
# Summary
|
|
self.stdout.write('\n' + '='*50)
|
|
self.stdout.write(
|
|
self.style.SUCCESS(f'Recommendation generation completed:')
|
|
)
|
|
self.stdout.write(f' Incidents processed: {success_count}')
|
|
self.stdout.write(f' Total recommendations generated: {total_recommendations}')
|
|
if error_count > 0:
|
|
self.stdout.write(
|
|
self.style.ERROR(f' Failed: {error_count}')
|
|
)
|
|
self.stdout.write('='*50)
|