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
15const size_t kMaxItems = 10000;
16
17
18class AbstractJobLogItem : public LogItem {
19public:
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
27protected:
28			BaseJob*			fJob;
29};
30
31
32class JobInitializedLogItem : public AbstractJobLogItem {
33public:
34								JobInitializedLogItem(Job* job);
35	virtual						~JobInitializedLogItem();
36
37	virtual	LogItemType			Type() const;
38	virtual status_t			GetMessage(BString& target) const;
39};
40
41
42class JobIgnoredLogItem : public LogItem {
43public:
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
53private:
54			BString				fJobName;
55			status_t			fError;
56};
57
58
59class JobLaunchedLogItem : public AbstractJobLogItem {
60public:
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
68private:
69			status_t			fStatus;
70};
71
72
73class JobTerminatedLogItem : public AbstractJobLogItem {
74public:
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
82private:
83			status_t			fStatus;
84};
85
86
87class JobEnabledLogItem : public AbstractJobLogItem {
88public:
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
96private:
97			bool				fEnabled;
98};
99
100
101class JobStoppedLogItem : public AbstractJobLogItem {
102public:
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
110private:
111			bool				fForce;
112};
113
114
115class EventLogItem : public AbstractJobLogItem {
116public:
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
126private:
127			Event*				fEvent;
128};
129
130
131class AbstractExternalEventLogItem : public LogItem {
132public:
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
140protected:
141			BString				fEventName;
142};
143
144
145class ExternalEventLogItem : public AbstractExternalEventLogItem {
146public:
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
155class ExternalEventRegisteredLogItem : public AbstractExternalEventLogItem {
156public:
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
166class ExternalEventUnregisteredLogItem : public AbstractExternalEventLogItem {
167public:
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
180LogItem::LogItem()
181	:
182	fWhen(system_time())
183{
184}
185
186
187LogItem::~LogItem()
188{
189}
190
191
192BString
193LogItem::Message() const
194{
195	BString message;
196	GetMessage(message);
197	return message;
198}
199
200
201// #pragma mark - Log
202
203
204Log::Log()
205	:
206	fCount(0)
207{
208	mutex_init(&fLock, "log lock");
209}
210
211
212void
213Log::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
225void
226Log::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
236void
237Log::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
249void
250Log::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
262void
263Log::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
275void
276Log::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
286void
287Log::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
297void
298Log::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
310void
311Log::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
321void
322Log::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
332void
333Log::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
346AbstractJobLogItem::AbstractJobLogItem(BaseJob* job)
347	:
348	fJob(job)
349{
350}
351
352
353AbstractJobLogItem::~AbstractJobLogItem()
354{
355}
356
357
358status_t
359AbstractJobLogItem::GetParameter(BMessage& parameter) const
360{
361	return parameter.AddString("job", fJob->Name());
362}
363
364
365bool
366AbstractJobLogItem::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
381JobInitializedLogItem::JobInitializedLogItem(Job* job)
382	:
383	AbstractJobLogItem(job)
384{
385}
386
387
388JobInitializedLogItem::~JobInitializedLogItem()
389{
390}
391
392
393LogItemType
394JobInitializedLogItem::Type() const
395{
396	return kJobInitialized;
397}
398
399
400status_t
401JobInitializedLogItem::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
411JobIgnoredLogItem::JobIgnoredLogItem(Job* job, status_t error)
412	:
413	fJobName(job->Name()),
414	fError(error)
415{
416}
417
418
419JobIgnoredLogItem::~JobIgnoredLogItem()
420{
421}
422
423
424LogItemType
425JobIgnoredLogItem::Type() const
426{
427	return kJobIgnored;
428}
429
430
431status_t
432JobIgnoredLogItem::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
440status_t
441JobIgnoredLogItem::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
450bool
451JobIgnoredLogItem::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
466JobLaunchedLogItem::JobLaunchedLogItem(Job* job, status_t status)
467	:
468	AbstractJobLogItem(job),
469	fStatus(status)
470{
471}
472
473
474JobLaunchedLogItem::~JobLaunchedLogItem()
475{
476}
477
478
479LogItemType
480JobLaunchedLogItem::Type() const
481{
482	return kJobLaunched;
483}
484
485
486status_t
487JobLaunchedLogItem::GetMessage(BString& target) const
488{
489	target.SetToFormat("Job \"%s\" launched: %s", fJob->Name(),
490		strerror(fStatus));
491	return B_OK;
492}
493
494
495status_t
496JobLaunchedLogItem::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
508JobTerminatedLogItem::JobTerminatedLogItem(Job* job, status_t status)
509	:
510	AbstractJobLogItem(job),
511	fStatus(status)
512{
513}
514
515
516JobTerminatedLogItem::~JobTerminatedLogItem()
517{
518}
519
520
521LogItemType
522JobTerminatedLogItem::Type() const
523{
524	return kJobTerminated;
525}
526
527
528status_t
529JobTerminatedLogItem::GetMessage(BString& target) const
530{
531	target.SetToFormat("Job \"%s\" terminated: %s", fJob->Name(),
532		strerror(fStatus));
533	return B_OK;
534}
535
536
537status_t
538JobTerminatedLogItem::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
550JobEnabledLogItem::JobEnabledLogItem(Job* job, bool enabled)
551	:
552	AbstractJobLogItem(job),
553	fEnabled(enabled)
554{
555}
556
557
558JobEnabledLogItem::~JobEnabledLogItem()
559{
560}
561
562
563LogItemType
564JobEnabledLogItem::Type() const
565{
566	return kJobEnabled;
567}
568
569
570status_t
571JobEnabledLogItem::GetMessage(BString& target) const
572{
573	target.SetToFormat("Job \"%s\" %sabled", fJob->Name(),
574		fEnabled ? "en" : "dis");
575	return B_OK;
576}
577
578
579status_t
580JobEnabledLogItem::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
592JobStoppedLogItem::JobStoppedLogItem(BaseJob* job, bool force)
593	:
594	AbstractJobLogItem(job),
595	fForce(force)
596{
597}
598
599
600JobStoppedLogItem::~JobStoppedLogItem()
601{
602}
603
604
605LogItemType
606JobStoppedLogItem::Type() const
607{
608	return kJobStopped;
609}
610
611
612status_t
613JobStoppedLogItem::GetMessage(BString& target) const
614{
615	target.SetToFormat("Job \"%s\" %sstopped", fJob->Name(),
616		fForce ? "force " : "");
617	return B_OK;
618}
619
620
621status_t
622JobStoppedLogItem::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
634EventLogItem::EventLogItem(BaseJob* job, Event* event)
635	:
636	AbstractJobLogItem(job),
637	fEvent(event)
638{
639}
640
641
642EventLogItem::~EventLogItem()
643{
644}
645
646
647LogItemType
648EventLogItem::Type() const
649{
650	return kEvent;
651}
652
653
654status_t
655EventLogItem::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
663status_t
664EventLogItem::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
673bool
674EventLogItem::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
686AbstractExternalEventLogItem::AbstractExternalEventLogItem(const char* name)
687	:
688	fEventName(name)
689{
690}
691
692
693AbstractExternalEventLogItem::~AbstractExternalEventLogItem()
694{
695}
696
697
698status_t
699AbstractExternalEventLogItem::GetParameter(BMessage& parameter) const
700{
701	return parameter.AddString("event", fEventName);
702}
703
704
705bool
706AbstractExternalEventLogItem::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
722ExternalEventLogItem::ExternalEventLogItem(const char* name)
723	:
724	AbstractExternalEventLogItem(name)
725{
726}
727
728
729ExternalEventLogItem::~ExternalEventLogItem()
730{
731}
732
733
734LogItemType
735ExternalEventLogItem::Type() const
736{
737	return kExternalEvent;
738}
739
740
741status_t
742ExternalEventLogItem::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
753ExternalEventRegisteredLogItem::ExternalEventRegisteredLogItem(const char* name)
754	:
755	AbstractExternalEventLogItem(name)
756{
757}
758
759
760ExternalEventRegisteredLogItem::~ExternalEventRegisteredLogItem()
761{
762}
763
764
765LogItemType
766ExternalEventRegisteredLogItem::Type() const
767{
768	return kExternalEventRegistered;
769}
770
771
772status_t
773ExternalEventRegisteredLogItem::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
784ExternalEventUnregisteredLogItem::ExternalEventUnregisteredLogItem(
785	const char* name)
786	:
787	AbstractExternalEventLogItem(name)
788{
789}
790
791
792ExternalEventUnregisteredLogItem::~ExternalEventUnregisteredLogItem()
793{
794}
795
796
797LogItemType
798ExternalEventUnregisteredLogItem::Type() const
799{
800	return kExternalEventUnregistered;
801}
802
803
804status_t
805ExternalEventUnregisteredLogItem::GetMessage(BString& target) const
806{
807	target.SetToFormat("External event unregistered: \"%s\"",
808		fEventName.String());
809	return B_OK;
810}
811