xref: /haiku/src/servers/launch/Log.cpp (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
1 /*
2  * Copyright 2017-2018, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "Log.h"
8 
9 #include <OS.h>
10 
11 #include "Events.h"
12 #include "Job.h"
13 
14 
15 const size_t kMaxItems = 10000;
16 
17 
18 class AbstractJobLogItem : public LogItem {
19 public:
20 								AbstractJobLogItem(BaseJob* job);
21 	virtual						~AbstractJobLogItem();
22 
23 	virtual status_t			GetParameter(BMessage& parameter) const;
24 	virtual	bool				Matches(const char* jobName,
25 									const char* eventName);
26 
27 protected:
28 			BaseJob*			fJob;
29 };
30 
31 
32 class JobInitializedLogItem : public AbstractJobLogItem {
33 public:
34 								JobInitializedLogItem(Job* job);
35 	virtual						~JobInitializedLogItem();
36 
37 	virtual	LogItemType			Type() const;
38 	virtual status_t			GetMessage(BString& target) const;
39 };
40 
41 
42 class JobIgnoredLogItem : public LogItem {
43 public:
44 								JobIgnoredLogItem(Job* job, status_t error);
45 	virtual						~JobIgnoredLogItem();
46 
47 	virtual	LogItemType			Type() const;
48 	virtual status_t			GetMessage(BString& target) const;
49 	virtual status_t			GetParameter(BMessage& parameter) const;
50 	virtual	bool				Matches(const char* jobName,
51 									const char* eventName);
52 
53 private:
54 			BString				fJobName;
55 			status_t			fError;
56 };
57 
58 
59 class JobLaunchedLogItem : public AbstractJobLogItem {
60 public:
61 								JobLaunchedLogItem(Job* job, status_t status);
62 	virtual						~JobLaunchedLogItem();
63 
64 	virtual	LogItemType			Type() const;
65 	virtual status_t			GetMessage(BString& target) const;
66 	virtual status_t			GetParameter(BMessage& parameter) const;
67 
68 private:
69 			status_t			fStatus;
70 };
71 
72 
73 class JobTerminatedLogItem : public AbstractJobLogItem {
74 public:
75 								JobTerminatedLogItem(Job* job, status_t status);
76 	virtual						~JobTerminatedLogItem();
77 
78 	virtual	LogItemType			Type() const;
79 	virtual status_t			GetMessage(BString& target) const;
80 	virtual status_t			GetParameter(BMessage& parameter) const;
81 
82 private:
83 			status_t			fStatus;
84 };
85 
86 
87 class JobEnabledLogItem : public AbstractJobLogItem {
88 public:
89 								JobEnabledLogItem(Job* job, bool enabled);
90 	virtual						~JobEnabledLogItem();
91 
92 	virtual	LogItemType			Type() const;
93 	virtual status_t			GetMessage(BString& target) const;
94 	virtual status_t			GetParameter(BMessage& parameter) const;
95 
96 private:
97 			bool				fEnabled;
98 };
99 
100 
101 class JobStoppedLogItem : public AbstractJobLogItem {
102 public:
103 								JobStoppedLogItem(BaseJob* job, bool force);
104 	virtual						~JobStoppedLogItem();
105 
106 	virtual	LogItemType			Type() const;
107 	virtual status_t			GetMessage(BString& target) const;
108 	virtual status_t			GetParameter(BMessage& parameter) const;
109 
110 private:
111 			bool				fForce;
112 };
113 
114 
115 class EventLogItem : public AbstractJobLogItem {
116 public:
117 								EventLogItem(BaseJob* job, Event* event);
118 	virtual						~EventLogItem();
119 
120 	virtual	LogItemType			Type() const;
121 	virtual status_t			GetMessage(BString& target) const;
122 	virtual status_t			GetParameter(BMessage& parameter) const;
123 	virtual	bool				Matches(const char* jobName,
124 									const char* eventName);
125 
126 private:
127 			Event*				fEvent;
128 };
129 
130 
131 class AbstractExternalEventLogItem : public LogItem {
132 public:
133 								AbstractExternalEventLogItem(const char* name);
134 	virtual						~AbstractExternalEventLogItem();
135 
136 	virtual status_t			GetParameter(BMessage& parameter) const;
137 	virtual	bool				Matches(const char* jobName,
138 									const char* eventName);
139 
140 protected:
141 			BString				fEventName;
142 };
143 
144 
145 class ExternalEventLogItem : public AbstractExternalEventLogItem {
146 public:
147 								ExternalEventLogItem(const char* name);
148 	virtual						~ExternalEventLogItem();
149 
150 	virtual	LogItemType			Type() const;
151 	virtual status_t			GetMessage(BString& target) const;
152 };
153 
154 
155 class ExternalEventRegisteredLogItem : public AbstractExternalEventLogItem {
156 public:
157 								ExternalEventRegisteredLogItem(
158 									const char* name);
159 	virtual						~ExternalEventRegisteredLogItem();
160 
161 	virtual	LogItemType			Type() const;
162 	virtual status_t			GetMessage(BString& target) const;
163 };
164 
165 
166 class ExternalEventUnregisteredLogItem : public AbstractExternalEventLogItem {
167 public:
168 								ExternalEventUnregisteredLogItem(
169 									const char* name);
170 	virtual						~ExternalEventUnregisteredLogItem();
171 
172 	virtual	LogItemType			Type() const;
173 	virtual status_t			GetMessage(BString& target) const;
174 };
175 
176 
177 // #pragma mark -
178 
179 
180 LogItem::LogItem()
181 	:
182 	fWhen(system_time())
183 {
184 }
185 
186 
187 LogItem::~LogItem()
188 {
189 }
190 
191 
192 BString
193 LogItem::Message() const
194 {
195 	BString message;
196 	GetMessage(message);
197 	return message;
198 }
199 
200 
201 // #pragma mark - Log
202 
203 
204 Log::Log()
205 	:
206 	fCount(0)
207 {
208 	mutex_init(&fLock, "log lock");
209 }
210 
211 
212 void
213 Log::Add(LogItem* item)
214 {
215 	MutexLocker locker(fLock);
216 	if (fCount == kMaxItems)
217 		fItems.Remove(fItems.First());
218 	else
219 		fCount++;
220 
221 	fItems.Add(item);
222 }
223 
224 
225 void
226 Log::JobInitialized(Job* job)
227 {
228 	LogItem* item = new(std::nothrow) JobInitializedLogItem(job);
229 	if (item != NULL)
230 		Add(item);
231 	else
232 		debug_printf("Initialized job \"%s\"\n", job->Name());
233 }
234 
235 
236 void
237 Log::JobIgnored(Job* job, status_t status)
238 {
239 	LogItem* item = new(std::nothrow) JobIgnoredLogItem(job, status);
240 	if (item != NULL)
241 		Add(item);
242 	else {
243 		debug_printf("Ignored job \"%s\": %s\n", job->Name(),
244 			strerror(status));
245 	}
246 }
247 
248 
249 void
250 Log::JobLaunched(Job* job, status_t status)
251 {
252 	LogItem* item = new(std::nothrow) JobLaunchedLogItem(job, status);
253 	if (item != NULL)
254 		Add(item);
255 	else {
256 		debug_printf("Launched job \"%s\": %s\n", job->Name(),
257 			strerror(status));
258 	}
259 }
260 
261 
262 void
263 Log::JobTerminated(Job* job, status_t status)
264 {
265 	LogItem* item = new(std::nothrow) JobTerminatedLogItem(job, status);
266 	if (item != NULL)
267 		Add(item);
268 	else {
269 		debug_printf("Terminated job \"%s\": %s\n", job->Name(),
270 			strerror(status));
271 	}
272 }
273 
274 
275 void
276 Log::JobEnabled(Job* job, bool enabled)
277 {
278 	LogItem* item = new(std::nothrow) JobEnabledLogItem(job, enabled);
279 	if (item != NULL)
280 		Add(item);
281 	else
282 		debug_printf("Enabled job \"%s\": %d\n", job->Name(), enabled);
283 }
284 
285 
286 void
287 Log::JobStopped(BaseJob* job, bool force)
288 {
289 	LogItem* item = new(std::nothrow) JobStoppedLogItem(job, force);
290 	if (item != NULL)
291 		Add(item);
292 	else
293 		debug_printf("Stopped job \"%s\"\n", job->Name());
294 }
295 
296 
297 void
298 Log::EventTriggered(BaseJob* job, Event* event)
299 {
300 	LogItem* item = new(std::nothrow) EventLogItem(job, event);
301 	if (item != NULL)
302 		Add(item);
303 	else {
304 		debug_printf("Event triggered for \"%s\": %s\n", job->Name(),
305 			event->ToString().String());
306 	}
307 }
308 
309 
310 void
311 Log::ExternalEventTriggered(const char* name)
312 {
313 	LogItem* item = new(std::nothrow) ExternalEventLogItem(name);
314 	if (item != NULL)
315 		Add(item);
316 	else
317 		debug_printf("External event triggered: %s\n", name);
318 }
319 
320 
321 void
322 Log::ExternalEventRegistered(const char* name)
323 {
324 	LogItem* item = new(std::nothrow) ExternalEventRegisteredLogItem(name);
325 	if (item != NULL)
326 		Add(item);
327 	else
328 		debug_printf("External event registered: %s\n", name);
329 }
330 
331 
332 void
333 Log::ExternalEventUnregistered(const char* name)
334 {
335 	LogItem* item = new(std::nothrow) ExternalEventUnregisteredLogItem(name);
336 	if (item != NULL)
337 		Add(item);
338 	else
339 		debug_printf("External event unregistered: %s\n", name);
340 }
341 
342 
343 // #pragma mark - AbstractJobLogItem
344 
345 
346 AbstractJobLogItem::AbstractJobLogItem(BaseJob* job)
347 	:
348 	fJob(job)
349 {
350 }
351 
352 
353 AbstractJobLogItem::~AbstractJobLogItem()
354 {
355 }
356 
357 
358 status_t
359 AbstractJobLogItem::GetParameter(BMessage& parameter) const
360 {
361 	return parameter.AddString("job", fJob->Name());
362 }
363 
364 
365 bool
366 AbstractJobLogItem::Matches(const char* jobName, const char* eventName)
367 {
368 	if (jobName == NULL && eventName == NULL)
369 		return true;
370 
371 	if (jobName != NULL && strcmp(fJob->Name(), jobName) == 0)
372 		return true;
373 
374 	return false;
375 }
376 
377 
378 // #pragma mark - JobInitializedLogItem
379 
380 
381 JobInitializedLogItem::JobInitializedLogItem(Job* job)
382 	:
383 	AbstractJobLogItem(job)
384 {
385 }
386 
387 
388 JobInitializedLogItem::~JobInitializedLogItem()
389 {
390 }
391 
392 
393 LogItemType
394 JobInitializedLogItem::Type() const
395 {
396 	return kJobInitialized;
397 }
398 
399 
400 status_t
401 JobInitializedLogItem::GetMessage(BString& target) const
402 {
403 	target.SetToFormat("Job \"%s\" initialized.", fJob->Name());
404 	return B_OK;
405 }
406 
407 
408 // #pragma mark - JobIgnoredLogItem
409 
410 
411 JobIgnoredLogItem::JobIgnoredLogItem(Job* job, status_t error)
412 	:
413 	fJobName(job->Name()),
414 	fError(error)
415 {
416 }
417 
418 
419 JobIgnoredLogItem::~JobIgnoredLogItem()
420 {
421 }
422 
423 
424 LogItemType
425 JobIgnoredLogItem::Type() const
426 {
427 	return kJobIgnored;
428 }
429 
430 
431 status_t
432 JobIgnoredLogItem::GetMessage(BString& target) const
433 {
434 	target.SetToFormat("Ignored job \"%s\" due %s", fJobName.String(),
435 		strerror(fError));
436 	return B_OK;
437 }
438 
439 
440 status_t
441 JobIgnoredLogItem::GetParameter(BMessage& parameter) const
442 {
443 	status_t status = parameter.AddString("job", fJobName);
444 	if (status == B_OK)
445 		status = parameter.AddInt32("error", fError);
446 	return status;
447 }
448 
449 
450 bool
451 JobIgnoredLogItem::Matches(const char* jobName, const char* eventName)
452 {
453 	if (jobName == NULL && eventName == NULL)
454 		return true;
455 
456 	if (jobName != NULL && fJobName == jobName)
457 		return true;
458 
459 	return false;
460 }
461 
462 
463 // #pragma mark - JobLaunchedLogItem
464 
465 
466 JobLaunchedLogItem::JobLaunchedLogItem(Job* job, status_t status)
467 	:
468 	AbstractJobLogItem(job),
469 	fStatus(status)
470 {
471 }
472 
473 
474 JobLaunchedLogItem::~JobLaunchedLogItem()
475 {
476 }
477 
478 
479 LogItemType
480 JobLaunchedLogItem::Type() const
481 {
482 	return kJobLaunched;
483 }
484 
485 
486 status_t
487 JobLaunchedLogItem::GetMessage(BString& target) const
488 {
489 	target.SetToFormat("Job \"%s\" launched: %s", fJob->Name(),
490 		strerror(fStatus));
491 	return B_OK;
492 }
493 
494 
495 status_t
496 JobLaunchedLogItem::GetParameter(BMessage& parameter) const
497 {
498 	status_t status = AbstractJobLogItem::GetParameter(parameter);
499 	if (status == B_OK)
500 		status = parameter.AddInt32("status", fStatus);
501 	return status;
502 }
503 
504 
505 // #pragma mark - JobTerminatedLogItem
506 
507 
508 JobTerminatedLogItem::JobTerminatedLogItem(Job* job, status_t status)
509 	:
510 	AbstractJobLogItem(job),
511 	fStatus(status)
512 {
513 }
514 
515 
516 JobTerminatedLogItem::~JobTerminatedLogItem()
517 {
518 }
519 
520 
521 LogItemType
522 JobTerminatedLogItem::Type() const
523 {
524 	return kJobTerminated;
525 }
526 
527 
528 status_t
529 JobTerminatedLogItem::GetMessage(BString& target) const
530 {
531 	target.SetToFormat("Job \"%s\" terminated: %s", fJob->Name(),
532 		strerror(fStatus));
533 	return B_OK;
534 }
535 
536 
537 status_t
538 JobTerminatedLogItem::GetParameter(BMessage& parameter) const
539 {
540 	status_t status = AbstractJobLogItem::GetParameter(parameter);
541 	if (status == B_OK)
542 		status = parameter.AddInt32("status", fStatus);
543 	return status;
544 }
545 
546 
547 // #pragma mark - JobEnabledLogItem
548 
549 
550 JobEnabledLogItem::JobEnabledLogItem(Job* job, bool enabled)
551 	:
552 	AbstractJobLogItem(job),
553 	fEnabled(enabled)
554 {
555 }
556 
557 
558 JobEnabledLogItem::~JobEnabledLogItem()
559 {
560 }
561 
562 
563 LogItemType
564 JobEnabledLogItem::Type() const
565 {
566 	return kJobEnabled;
567 }
568 
569 
570 status_t
571 JobEnabledLogItem::GetMessage(BString& target) const
572 {
573 	target.SetToFormat("Job \"%s\" %sabled", fJob->Name(),
574 		fEnabled ? "en" : "dis");
575 	return B_OK;
576 }
577 
578 
579 status_t
580 JobEnabledLogItem::GetParameter(BMessage& parameter) const
581 {
582 	status_t status = AbstractJobLogItem::GetParameter(parameter);
583 	if (status == B_OK)
584 		status = parameter.AddBool("enabled", fEnabled);
585 	return status;
586 }
587 
588 
589 // #pragma mark - JobStoppedLogItem
590 
591 
592 JobStoppedLogItem::JobStoppedLogItem(BaseJob* job, bool force)
593 	:
594 	AbstractJobLogItem(job),
595 	fForce(force)
596 {
597 }
598 
599 
600 JobStoppedLogItem::~JobStoppedLogItem()
601 {
602 }
603 
604 
605 LogItemType
606 JobStoppedLogItem::Type() const
607 {
608 	return kJobStopped;
609 }
610 
611 
612 status_t
613 JobStoppedLogItem::GetMessage(BString& target) const
614 {
615 	target.SetToFormat("Job \"%s\" %sstopped", fJob->Name(),
616 		fForce ? "force " : "");
617 	return B_OK;
618 }
619 
620 
621 status_t
622 JobStoppedLogItem::GetParameter(BMessage& parameter) const
623 {
624 	status_t status = AbstractJobLogItem::GetParameter(parameter);
625 	if (status == B_OK)
626 		status = parameter.AddBool("force", fForce);
627 	return status;
628 }
629 
630 
631 // #pragma mark - EventLogItem
632 
633 
634 EventLogItem::EventLogItem(BaseJob* job, Event* event)
635 	:
636 	AbstractJobLogItem(job),
637 	fEvent(event)
638 {
639 }
640 
641 
642 EventLogItem::~EventLogItem()
643 {
644 }
645 
646 
647 LogItemType
648 EventLogItem::Type() const
649 {
650 	return kEvent;
651 }
652 
653 
654 status_t
655 EventLogItem::GetMessage(BString& target) const
656 {
657 	target.SetToFormat("Event triggered \"%s\": \"%s\"", fJob->Name(),
658 		fEvent->ToString().String());
659 	return B_OK;
660 }
661 
662 
663 status_t
664 EventLogItem::GetParameter(BMessage& parameter) const
665 {
666 	status_t status = AbstractJobLogItem::GetParameter(parameter);
667 	if (status == B_OK)
668 		status = parameter.AddString("event", fEvent->ToString());
669 	return status;
670 }
671 
672 
673 bool
674 EventLogItem::Matches(const char* jobName, const char* eventName)
675 {
676 	if (eventName != NULL && strstr(fEvent->ToString(), eventName) == NULL)
677 		return false;
678 
679 	return AbstractJobLogItem::Matches(jobName, NULL);
680 }
681 
682 
683 // #pragma mark - ExternalEventLogItem
684 
685 
686 AbstractExternalEventLogItem::AbstractExternalEventLogItem(const char* name)
687 	:
688 	fEventName(name)
689 {
690 }
691 
692 
693 AbstractExternalEventLogItem::~AbstractExternalEventLogItem()
694 {
695 }
696 
697 
698 status_t
699 AbstractExternalEventLogItem::GetParameter(BMessage& parameter) const
700 {
701 	return parameter.AddString("event", fEventName);
702 }
703 
704 
705 bool
706 AbstractExternalEventLogItem::Matches(const char* jobName,
707 	const char* eventName)
708 {
709 	if (jobName == NULL && eventName == NULL)
710 		return true;
711 
712 	if (eventName != NULL && strstr(fEventName.String(), eventName) != NULL)
713 		return true;
714 
715 	return false;
716 }
717 
718 
719 // #pragma mark - ExternalEventLogItem
720 
721 
722 ExternalEventLogItem::ExternalEventLogItem(const char* name)
723 	:
724 	AbstractExternalEventLogItem(name)
725 {
726 }
727 
728 
729 ExternalEventLogItem::~ExternalEventLogItem()
730 {
731 }
732 
733 
734 LogItemType
735 ExternalEventLogItem::Type() const
736 {
737 	return kExternalEvent;
738 }
739 
740 
741 status_t
742 ExternalEventLogItem::GetMessage(BString& target) const
743 {
744 	target.SetToFormat("External event triggered: \"%s\"",
745 		fEventName.String());
746 	return B_OK;
747 }
748 
749 
750 // #pragma mark - ExternalEventRegisteredLogItem
751 
752 
753 ExternalEventRegisteredLogItem::ExternalEventRegisteredLogItem(const char* name)
754 	:
755 	AbstractExternalEventLogItem(name)
756 {
757 }
758 
759 
760 ExternalEventRegisteredLogItem::~ExternalEventRegisteredLogItem()
761 {
762 }
763 
764 
765 LogItemType
766 ExternalEventRegisteredLogItem::Type() const
767 {
768 	return kExternalEventRegistered;
769 }
770 
771 
772 status_t
773 ExternalEventRegisteredLogItem::GetMessage(BString& target) const
774 {
775 	target.SetToFormat("External event registered: \"%s\"",
776 		fEventName.String());
777 	return B_OK;
778 }
779 
780 
781 // #pragma mark - ExternalEventUnregisteredLogItem
782 
783 
784 ExternalEventUnregisteredLogItem::ExternalEventUnregisteredLogItem(
785 	const char* name)
786 	:
787 	AbstractExternalEventLogItem(name)
788 {
789 }
790 
791 
792 ExternalEventUnregisteredLogItem::~ExternalEventUnregisteredLogItem()
793 {
794 }
795 
796 
797 LogItemType
798 ExternalEventUnregisteredLogItem::Type() const
799 {
800 	return kExternalEventUnregistered;
801 }
802 
803 
804 status_t
805 ExternalEventUnregisteredLogItem::GetMessage(BString& target) const
806 {
807 	target.SetToFormat("External event unregistered: \"%s\"",
808 		fEventName.String());
809 	return B_OK;
810 }
811