1use crate::errors::ThreadError;
4use crate::security::{SecurityConfig, SecurityViolation};
5use crate::thread_new::ThreadId;
6use portable_atomic::{AtomicU64, AtomicUsize, Ordering};
7use alloc::{collections::VecDeque, string::String, vec::Vec, format};
8use core::fmt::Write;
9
10pub struct AuditLogger {
12 event_buffer: VecDeque<AuditEvent>,
14 max_buffer_size: usize,
16 events_logged: AtomicU64,
18 security_violations: AtomicUsize,
20 log_level: AuditLevel,
22 enabled_categories: AuditCategories,
24}
25
26impl AuditLogger {
27 pub fn new(config: AuditConfig) -> Self {
28 Self {
29 event_buffer: VecDeque::with_capacity(config.max_buffer_size),
30 max_buffer_size: config.max_buffer_size,
31 events_logged: AtomicU64::new(0),
32 security_violations: AtomicUsize::new(0),
33 log_level: config.log_level,
34 enabled_categories: config.enabled_categories,
35 }
36 }
37
38 pub fn log_security_violation(
40 &mut self,
41 violation: SecurityViolation,
42 thread_id: Option<ThreadId>,
43 details: &str,
44 ) {
45 if !self.enabled_categories.security {
46 return;
47 }
48
49 let event = AuditEvent::new(
50 AuditEventType::SecurityViolation {
51 violation_type: violation,
52 thread_id,
53 details: String::from(details),
54 },
55 AuditLevel::Critical,
56 self.get_current_context(),
57 );
58
59 self.log_event(event);
60 self.security_violations.fetch_add(1, Ordering::Relaxed);
61 }
62
63 pub fn log_thread_event(
65 &mut self,
66 thread_id: ThreadId,
67 event_type: ThreadEventType,
68 details: &str,
69 ) {
70 if !self.enabled_categories.thread_lifecycle {
71 return;
72 }
73
74 let event = AuditEvent::new(
75 AuditEventType::ThreadLifecycle {
76 thread_id,
77 event_type,
78 details: String::from(details),
79 },
80 AuditLevel::Info,
81 self.get_current_context(),
82 );
83
84 self.log_event(event);
85 }
86
87 pub fn log_memory_event(
89 &mut self,
90 operation: MemoryOperation,
91 address: usize,
92 size: usize,
93 thread_id: Option<ThreadId>,
94 ) {
95 if !self.enabled_categories.memory_operations {
96 return;
97 }
98
99 let event = AuditEvent::new(
100 AuditEventType::MemoryOperation {
101 operation,
102 address,
103 size,
104 thread_id,
105 },
106 AuditLevel::Debug,
107 self.get_current_context(),
108 );
109
110 self.log_event(event);
111 }
112
113 pub fn log_scheduler_event(
115 &mut self,
116 event_type: SchedulerEventType,
117 thread_id: Option<ThreadId>,
118 details: &str,
119 ) {
120 if !self.enabled_categories.scheduler_events {
121 return;
122 }
123
124 let level = match event_type {
125 SchedulerEventType::PreemptionOverride => AuditLevel::Warning,
126 _ => AuditLevel::Debug,
127 };
128
129 let event = AuditEvent::new(
130 AuditEventType::SchedulerEvent {
131 event_type,
132 thread_id,
133 details: String::from(details),
134 },
135 level,
136 self.get_current_context(),
137 );
138
139 self.log_event(event);
140 }
141
142 pub fn log_performance_event(
144 &mut self,
145 metric: PerformanceMetric,
146 value: u64,
147 threshold: Option<u64>,
148 ) {
149 if !self.enabled_categories.performance {
150 return;
151 }
152
153 let level = if let Some(thresh) = threshold {
154 if value > thresh {
155 AuditLevel::Warning
156 } else {
157 AuditLevel::Debug
158 }
159 } else {
160 AuditLevel::Debug
161 };
162
163 let event = AuditEvent::new(
164 AuditEventType::Performance {
165 metric,
166 value,
167 threshold,
168 },
169 level,
170 self.get_current_context(),
171 );
172
173 self.log_event(event);
174 }
175
176 pub fn log_system_event(&mut self, event_type: SystemEventType, details: &str) {
178 if !self.enabled_categories.system_events {
179 return;
180 }
181
182 let level = match event_type {
183 SystemEventType::Initialization | SystemEventType::Shutdown => AuditLevel::Info,
184 SystemEventType::ConfigurationChange => AuditLevel::Warning,
185 SystemEventType::ResourceExhaustion => AuditLevel::Critical,
186 _ => AuditLevel::Debug,
187 };
188
189 let event = AuditEvent::new(
190 AuditEventType::System {
191 event_type,
192 details: String::from(details),
193 },
194 level,
195 self.get_current_context(),
196 );
197
198 self.log_event(event);
199 }
200
201 fn log_event(&mut self, event: AuditEvent) {
203 if event.level < self.log_level {
205 return;
206 }
207
208 if self.event_buffer.len() >= self.max_buffer_size {
210 self.event_buffer.pop_front();
211 }
212 self.event_buffer.push_back(event);
213
214 self.events_logged.fetch_add(1, Ordering::Relaxed);
215 }
216
217 fn get_current_context(&self) -> AuditContext {
219 AuditContext {
220 timestamp: crate::time::get_monotonic_time().as_nanos() as u64,
221 current_thread: crate::thread_new::current_thread_id(),
222 cpu_id: 0, interrupt_context: false, }
225 }
226
227 pub fn get_recent_events(&self, count: usize) -> Vec<AuditEvent> {
229 self.event_buffer
230 .iter()
231 .rev()
232 .take(count)
233 .cloned()
234 .collect()
235 }
236
237 pub fn search_events(&self, criteria: &SearchCriteria) -> Vec<AuditEvent> {
239 self.event_buffer
240 .iter()
241 .filter(|event| criteria.matches(event))
242 .cloned()
243 .collect()
244 }
245
246 pub fn export_events(&self, format: ExportFormat) -> Result<String, ThreadError> {
248 let mut output = String::new();
249
250 match format {
251 ExportFormat::Json => {
252 writeln!(output, "[").map_err(|_| ThreadError::Other("Format error".into()))?;
253 for (i, event) in self.event_buffer.iter().enumerate() {
254 if i > 0 {
255 writeln!(output, ",").map_err(|_| ThreadError::Other("Format error".into()))?;
256 }
257 writeln!(output, " {}", event.to_json()).map_err(|_| ThreadError::Other("Format error".into()))?;
258 }
259 writeln!(output, "]").map_err(|_| ThreadError::Other("Format error".into()))?;
260 },
261 ExportFormat::Csv => {
262 writeln!(output, "timestamp,level,category,thread_id,details").map_err(|_| ThreadError::Other("Format error".into()))?;
263 for event in &self.event_buffer {
264 writeln!(output, "{}", event.to_csv()).map_err(|_| ThreadError::Other("Format error".into()))?;
265 }
266 },
267 ExportFormat::Plain => {
268 for event in &self.event_buffer {
269 writeln!(output, "{}", event).map_err(|_| ThreadError::Other("Format error".into()))?;
270 }
271 },
272 }
273
274 Ok(output)
275 }
276}
277
278#[derive(Debug, Clone)]
280pub struct AuditEvent {
281 pub event_type: AuditEventType,
282 pub level: AuditLevel,
283 pub context: AuditContext,
284}
285
286impl AuditEvent {
287 fn new(event_type: AuditEventType, level: AuditLevel, context: AuditContext) -> Self {
288 Self {
289 event_type,
290 level,
291 context,
292 }
293 }
294
295 fn to_json(&self) -> String {
297 format!(
298 "{{\"timestamp\":{},\"level\":\"{:?}\",\"thread_id\":{},\"event\":\"{}\"}}",
299 self.context.timestamp,
300 self.level,
301 self.context.current_thread,
302 self.event_type.description()
303 )
304 }
305
306 fn to_csv(&self) -> String {
308 format!(
309 "{},{:?},{},{},\"{}\"",
310 self.context.timestamp,
311 self.level,
312 self.event_type.category(),
313 self.context.current_thread,
314 self.event_type.description().replace("\"", "\"\"")
315 )
316 }
317}
318
319impl core::fmt::Display for AuditEvent {
320 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
321 write!(
322 f,
323 "[{}] {:?} [T:{}] {}",
324 self.context.timestamp,
325 self.level,
326 self.context.current_thread,
327 self.event_type.description()
328 )
329 }
330}
331
332#[derive(Debug, Clone)]
334pub enum AuditEventType {
335 SecurityViolation {
336 violation_type: SecurityViolation,
337 thread_id: Option<ThreadId>,
338 details: String,
339 },
340 ThreadLifecycle {
341 thread_id: ThreadId,
342 event_type: ThreadEventType,
343 details: String,
344 },
345 MemoryOperation {
346 operation: MemoryOperation,
347 address: usize,
348 size: usize,
349 thread_id: Option<ThreadId>,
350 },
351 SchedulerEvent {
352 event_type: SchedulerEventType,
353 thread_id: Option<ThreadId>,
354 details: String,
355 },
356 Performance {
357 metric: PerformanceMetric,
358 value: u64,
359 threshold: Option<u64>,
360 },
361 System {
362 event_type: SystemEventType,
363 details: String,
364 },
365}
366
367impl AuditEventType {
368 fn category(&self) -> &'static str {
369 match self {
370 AuditEventType::SecurityViolation { .. } => "security",
371 AuditEventType::ThreadLifecycle { .. } => "thread",
372 AuditEventType::MemoryOperation { .. } => "memory",
373 AuditEventType::SchedulerEvent { .. } => "scheduler",
374 AuditEventType::Performance { .. } => "performance",
375 AuditEventType::System { .. } => "system",
376 }
377 }
378
379 fn description(&self) -> String {
380 match self {
381 AuditEventType::SecurityViolation { violation_type, details, .. } => {
382 format!("Security violation: {:?} - {}", violation_type, details)
383 },
384 AuditEventType::ThreadLifecycle { event_type, details, .. } => {
385 format!("Thread {:?}: {}", event_type, details)
386 },
387 AuditEventType::MemoryOperation { operation, address, size, .. } => {
388 format!("Memory {:?}: addr=0x{:x} size={}", operation, address, size)
389 },
390 AuditEventType::SchedulerEvent { event_type, details, .. } => {
391 format!("Scheduler {:?}: {}", event_type, details)
392 },
393 AuditEventType::Performance { metric, value, threshold } => {
394 if let Some(thresh) = threshold {
395 format!("Performance {:?}: {} (threshold: {})", metric, value, thresh)
396 } else {
397 format!("Performance {:?}: {}", metric, value)
398 }
399 },
400 AuditEventType::System { event_type, details } => {
401 format!("System {:?}: {}", event_type, details)
402 },
403 }
404 }
405}
406
407#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
409pub enum AuditLevel {
410 Debug,
411 Info,
412 Warning,
413 Critical,
414}
415
416#[derive(Debug, Clone)]
418pub struct AuditContext {
419 pub timestamp: u64,
420 pub current_thread: ThreadId,
421 pub cpu_id: u32,
422 pub interrupt_context: bool,
423}
424
425#[derive(Debug, Clone, Copy)]
427pub enum ThreadEventType {
428 Created,
429 Started,
430 Suspended,
431 Resumed,
432 Terminated,
433 Joined,
434 Detached,
435}
436
437#[derive(Debug, Clone, Copy)]
439pub enum MemoryOperation {
440 Allocate,
441 Deallocate,
442 Protect,
443 Unprotect,
444 Map,
445 Unmap,
446 Access,
447}
448
449#[derive(Debug, Clone, Copy)]
451pub enum SchedulerEventType {
452 ContextSwitch,
453 Preemption,
454 PreemptionOverride,
455 ThreadMigration,
456 PriorityChange,
457 AffinityChange,
458}
459
460#[derive(Debug, Clone, Copy)]
462pub enum PerformanceMetric {
463 ContextSwitchTime,
464 SchedulingLatency,
465 MemoryUsage,
466 CpuUtilization,
467 ThreadCount,
468 LockContention,
469}
470
471#[derive(Debug, Clone, Copy)]
473pub enum SystemEventType {
474 Initialization,
475 Shutdown,
476 ConfigurationChange,
477 ResourceExhaustion,
478 HardwareEvent,
479 ErrorRecovery,
480}
481
482#[derive(Debug, Clone)]
484pub struct AuditConfig {
485 pub log_level: AuditLevel,
486 pub max_buffer_size: usize,
487 pub enabled_categories: AuditCategories,
488 pub export_format: ExportFormat,
489}
490
491impl Default for AuditConfig {
492 fn default() -> Self {
493 Self {
494 log_level: AuditLevel::Info,
495 max_buffer_size: 10000,
496 enabled_categories: AuditCategories::default(),
497 export_format: ExportFormat::Plain,
498 }
499 }
500}
501
502#[derive(Debug, Clone)]
504pub struct AuditCategories {
505 pub security: bool,
506 pub thread_lifecycle: bool,
507 pub memory_operations: bool,
508 pub scheduler_events: bool,
509 pub performance: bool,
510 pub system_events: bool,
511}
512
513impl Default for AuditCategories {
514 fn default() -> Self {
515 Self {
516 security: true,
517 thread_lifecycle: true,
518 memory_operations: false, scheduler_events: false, performance: true,
521 system_events: true,
522 }
523 }
524}
525
526#[derive(Debug)]
528pub struct SearchCriteria {
529 pub level_filter: Option<AuditLevel>,
530 pub category_filter: Option<String>,
531 pub thread_filter: Option<ThreadId>,
532 pub time_range: Option<(u64, u64)>,
533}
534
535impl SearchCriteria {
536 fn matches(&self, event: &AuditEvent) -> bool {
537 if let Some(level) = self.level_filter {
538 if event.level < level {
539 return false;
540 }
541 }
542
543 if let Some(ref category) = self.category_filter {
544 if event.event_type.category() != category {
545 return false;
546 }
547 }
548
549 if let Some(thread_id) = self.thread_filter {
550 if event.context.current_thread != thread_id {
551 return false;
552 }
553 }
554
555 if let Some((start, end)) = self.time_range {
556 if event.context.timestamp < start || event.context.timestamp > end {
557 return false;
558 }
559 }
560
561 true
562 }
563}
564
565#[derive(Debug, Clone, Copy)]
567pub enum ExportFormat {
568 Json,
569 Csv,
570 Plain,
571}
572
573#[derive(Debug, Clone)]
575pub struct AuditStats {
576 pub events_logged: u64,
577 pub security_violations: usize,
578 pub buffer_size: usize,
579 pub max_buffer_size: usize,
580 pub audit_enabled: bool,
581}
582
583static mut AUDIT_LOGGER: Option<AuditLogger> = None;
585
586pub fn init_audit_logging(config: SecurityConfig) -> Result<(), ThreadError> {
588 let audit_config = AuditConfig {
589 log_level: if cfg!(debug_assertions) {
590 AuditLevel::Debug
591 } else {
592 AuditLevel::Info
593 },
594 max_buffer_size: 10000,
595 enabled_categories: AuditCategories::default(),
596 export_format: ExportFormat::Plain,
597 };
598
599 unsafe {
600 AUDIT_LOGGER = Some(AuditLogger::new(audit_config));
601 }
602
603 log_system_event(SystemEventType::Initialization, "Audit logging system initialized");
604 Ok(())
607}
608
609pub fn log_security_violation(violation: SecurityViolation) {
611 let thread_id = Some(crate::thread_new::current_thread_id());
612 let details = format!("Security violation detected in thread {}", thread_id.unwrap());
613
614 unsafe {
615 if let Some(logger) = &mut AUDIT_LOGGER {
616 logger.log_security_violation(violation, thread_id, &details);
617 }
618 }
619}
620
621pub fn log_thread_event(thread_id: ThreadId, event_type: ThreadEventType, details: &str) {
623 unsafe {
624 if let Some(logger) = &mut AUDIT_LOGGER {
625 logger.log_thread_event(thread_id, event_type, details);
626 }
627 }
628}
629
630pub fn log_memory_event(operation: MemoryOperation, address: usize, size: usize) {
632 let thread_id = Some(crate::thread_new::current_thread_id());
633
634 unsafe {
635 if let Some(logger) = &mut AUDIT_LOGGER {
636 logger.log_memory_event(operation, address, size, thread_id);
637 }
638 }
639}
640
641pub fn log_scheduler_event(event_type: SchedulerEventType, thread_id: Option<ThreadId>, details: &str) {
643 unsafe {
644 if let Some(logger) = &mut AUDIT_LOGGER {
645 logger.log_scheduler_event(event_type, thread_id, details);
646 }
647 }
648}
649
650pub fn log_performance_event(metric: PerformanceMetric, value: u64, threshold: Option<u64>) {
652 unsafe {
653 if let Some(logger) = &mut AUDIT_LOGGER {
654 logger.log_performance_event(metric, value, threshold);
655 }
656 }
657}
658
659pub fn log_system_event(event_type: SystemEventType, details: &str) {
661 unsafe {
662 if let Some(logger) = &mut AUDIT_LOGGER {
663 logger.log_system_event(event_type, details);
664 }
665 }
666}
667
668pub fn get_recent_audit_events(count: usize) -> Vec<AuditEvent> {
670 unsafe {
671 match &AUDIT_LOGGER {
672 Some(logger) => logger.get_recent_events(count),
673 None => Vec::new(),
674 }
675 }
676}
677
678pub fn search_audit_events(criteria: &SearchCriteria) -> Vec<AuditEvent> {
680 unsafe {
681 match &AUDIT_LOGGER {
682 Some(logger) => logger.search_events(criteria),
683 None => Vec::new(),
684 }
685 }
686}
687
688pub fn export_audit_events(format: ExportFormat) -> Result<String, ThreadError> {
690 unsafe {
691 match &AUDIT_LOGGER {
692 Some(logger) => logger.export_events(format),
693 None => Ok(String::new()),
694 }
695 }
696}
697
698pub fn get_audit_stats() -> AuditStats {
700 unsafe {
701 match &AUDIT_LOGGER {
702 Some(logger) => AuditStats {
703 events_logged: logger.events_logged.load(Ordering::Relaxed),
704 security_violations: logger.security_violations.load(Ordering::Relaxed),
705 buffer_size: logger.event_buffer.len(),
706 max_buffer_size: logger.max_buffer_size,
707 audit_enabled: true,
708 },
709 None => AuditStats {
710 events_logged: 0,
711 security_violations: 0,
712 buffer_size: 0,
713 max_buffer_size: 0,
714 audit_enabled: false,
715 },
716 }
717 }
718}