* Copyright 2017-2018, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include "Log.h"
#include <OS.h>
#include "Events.h"
#include "Job.h"
const size_t kMaxItems = 10000;
class AbstractJobLogItem : public LogItem {
public:
AbstractJobLogItem(BaseJob* job);
virtual ~AbstractJobLogItem();
virtual status_t GetParameter(BMessage& parameter) const;
virtual bool Matches(const char* jobName,
const char* eventName);
protected:
BaseJob* fJob;
};
class JobInitializedLogItem : public AbstractJobLogItem {
public:
JobInitializedLogItem(Job* job);
virtual ~JobInitializedLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
};
class JobIgnoredLogItem : public LogItem {
public:
JobIgnoredLogItem(Job* job, status_t error);
virtual ~JobIgnoredLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
virtual status_t GetParameter(BMessage& parameter) const;
virtual bool Matches(const char* jobName,
const char* eventName);
private:
BString fJobName;
status_t fError;
};
class JobSkippedLogItem : public LogItem {
public:
JobSkippedLogItem(Job* job);
virtual ~JobSkippedLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
virtual status_t GetParameter(BMessage& parameter) const;
virtual bool Matches(const char* jobName,
const char* eventName);
private:
BString fJobName;
};
class JobLaunchedLogItem : public AbstractJobLogItem {
public:
JobLaunchedLogItem(Job* job, status_t status);
virtual ~JobLaunchedLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
virtual status_t GetParameter(BMessage& parameter) const;
private:
status_t fStatus;
};
class JobTerminatedLogItem : public AbstractJobLogItem {
public:
JobTerminatedLogItem(Job* job, status_t status);
virtual ~JobTerminatedLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
virtual status_t GetParameter(BMessage& parameter) const;
private:
status_t fStatus;
};
class JobEnabledLogItem : public AbstractJobLogItem {
public:
JobEnabledLogItem(Job* job, bool enabled);
virtual ~JobEnabledLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
virtual status_t GetParameter(BMessage& parameter) const;
private:
bool fEnabled;
};
class JobStoppedLogItem : public AbstractJobLogItem {
public:
JobStoppedLogItem(BaseJob* job, bool force);
virtual ~JobStoppedLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
virtual status_t GetParameter(BMessage& parameter) const;
private:
bool fForce;
};
class EventLogItem : public AbstractJobLogItem {
public:
EventLogItem(BaseJob* job, Event* event);
virtual ~EventLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
virtual status_t GetParameter(BMessage& parameter) const;
virtual bool Matches(const char* jobName,
const char* eventName);
private:
Event* fEvent;
};
class AbstractExternalEventLogItem : public LogItem {
public:
AbstractExternalEventLogItem(const char* name);
virtual ~AbstractExternalEventLogItem();
virtual status_t GetParameter(BMessage& parameter) const;
virtual bool Matches(const char* jobName,
const char* eventName);
protected:
BString fEventName;
};
class ExternalEventLogItem : public AbstractExternalEventLogItem {
public:
ExternalEventLogItem(const char* name);
virtual ~ExternalEventLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
};
class ExternalEventRegisteredLogItem : public AbstractExternalEventLogItem {
public:
ExternalEventRegisteredLogItem(
const char* name);
virtual ~ExternalEventRegisteredLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
};
class ExternalEventUnregisteredLogItem : public AbstractExternalEventLogItem {
public:
ExternalEventUnregisteredLogItem(
const char* name);
virtual ~ExternalEventUnregisteredLogItem();
virtual LogItemType Type() const;
virtual status_t GetMessage(BString& target) const;
};
LogItem::LogItem()
:
fWhen(system_time())
{
}
LogItem::~LogItem()
{
}
BString
LogItem::Message() const
{
BString message;
GetMessage(message);
return message;
}
Log::Log()
:
fCount(0)
{
mutex_init(&fLock, "log lock");
}
void
Log::Add(LogItem* item)
{
MutexLocker locker(fLock);
if (fCount == kMaxItems)
fItems.Remove(fItems.First());
else
fCount++;
fItems.Add(item);
}
void
Log::JobInitialized(Job* job)
{
LogItem* item = new(std::nothrow) JobInitializedLogItem(job);
if (item != NULL)
Add(item);
else
debug_printf("Initialized job \"%s\"\n", job->Name());
}
void
Log::JobIgnored(Job* job, status_t status)
{
LogItem* item = new(std::nothrow) JobIgnoredLogItem(job, status);
if (item != NULL)
Add(item);
else {
debug_printf("Ignored job \"%s\": %s\n", job->Name(),
strerror(status));
}
}
void
Log::JobSkipped(Job* job)
{
LogItem* item = new(std::nothrow) JobSkippedLogItem(job);
if (item != NULL)
Add(item);
else {
debug_printf("Skipped job \"%s\"\n", job->Name());
}
}
void
Log::JobLaunched(Job* job, status_t status)
{
LogItem* item = new(std::nothrow) JobLaunchedLogItem(job, status);
if (item != NULL)
Add(item);
else {
debug_printf("Launched job \"%s\": %s\n", job->Name(),
strerror(status));
}
}
void
Log::JobTerminated(Job* job, status_t status)
{
LogItem* item = new(std::nothrow) JobTerminatedLogItem(job, status);
if (item != NULL)
Add(item);
else {
debug_printf("Terminated job \"%s\": %s\n", job->Name(),
strerror(status));
}
}
void
Log::JobEnabled(Job* job, bool enabled)
{
LogItem* item = new(std::nothrow) JobEnabledLogItem(job, enabled);
if (item != NULL)
Add(item);
else
debug_printf("Enabled job \"%s\": %d\n", job->Name(), enabled);
}
void
Log::JobStopped(BaseJob* job, bool force)
{
LogItem* item = new(std::nothrow) JobStoppedLogItem(job, force);
if (item != NULL)
Add(item);
else
debug_printf("Stopped job \"%s\"\n", job->Name());
}
void
Log::EventTriggered(BaseJob* job, Event* event)
{
LogItem* item = new(std::nothrow) EventLogItem(job, event);
if (item != NULL)
Add(item);
else {
debug_printf("Event triggered for \"%s\": %s\n", job->Name(),
event->ToString().String());
}
}
void
Log::ExternalEventTriggered(const char* name)
{
LogItem* item = new(std::nothrow) ExternalEventLogItem(name);
if (item != NULL)
Add(item);
else
debug_printf("External event triggered: %s\n", name);
}
void
Log::ExternalEventRegistered(const char* name)
{
LogItem* item = new(std::nothrow) ExternalEventRegisteredLogItem(name);
if (item != NULL)
Add(item);
else
debug_printf("External event registered: %s\n", name);
}
void
Log::ExternalEventUnregistered(const char* name)
{
LogItem* item = new(std::nothrow) ExternalEventUnregisteredLogItem(name);
if (item != NULL)
Add(item);
else
debug_printf("External event unregistered: %s\n", name);
}
AbstractJobLogItem::AbstractJobLogItem(BaseJob* job)
:
fJob(job)
{
}
AbstractJobLogItem::~AbstractJobLogItem()
{
}
status_t
AbstractJobLogItem::GetParameter(BMessage& parameter) const
{
return parameter.AddString("job", fJob->Name());
}
bool
AbstractJobLogItem::Matches(const char* jobName, const char* eventName)
{
if (jobName == NULL && eventName == NULL)
return true;
if (jobName != NULL && strcmp(fJob->Name(), jobName) == 0)
return true;
return false;
}
JobInitializedLogItem::JobInitializedLogItem(Job* job)
:
AbstractJobLogItem(job)
{
}
JobInitializedLogItem::~JobInitializedLogItem()
{
}
LogItemType
JobInitializedLogItem::Type() const
{
return kJobInitialized;
}
status_t
JobInitializedLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Job \"%s\" initialized.", fJob->Name());
return B_OK;
}
JobIgnoredLogItem::JobIgnoredLogItem(Job* job, status_t error)
:
fJobName(job->Name()),
fError(error)
{
}
JobIgnoredLogItem::~JobIgnoredLogItem()
{
}
LogItemType
JobIgnoredLogItem::Type() const
{
return kJobIgnored;
}
status_t
JobIgnoredLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Ignored job \"%s\" due %s", fJobName.String(),
strerror(fError));
return B_OK;
}
status_t
JobIgnoredLogItem::GetParameter(BMessage& parameter) const
{
status_t status = parameter.AddString("job", fJobName);
if (status == B_OK)
status = parameter.AddInt32("error", fError);
return status;
}
bool
JobIgnoredLogItem::Matches(const char* jobName, const char* eventName)
{
if (jobName == NULL && eventName == NULL)
return true;
if (jobName != NULL && fJobName == jobName)
return true;
return false;
}
JobSkippedLogItem::JobSkippedLogItem(Job* job)
:
fJobName(job->Name())
{
}
JobSkippedLogItem::~JobSkippedLogItem()
{
}
LogItemType
JobSkippedLogItem::Type() const
{
return kJobSkipped;
}
status_t
JobSkippedLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Skipped job \"%s\"", fJobName.String());
return B_OK;
}
status_t
JobSkippedLogItem::GetParameter(BMessage& parameter) const
{
return parameter.AddString("job", fJobName);
}
bool
JobSkippedLogItem::Matches(const char* jobName, const char* eventName)
{
if (jobName == NULL && eventName == NULL)
return true;
if (jobName != NULL && fJobName == jobName)
return true;
return false;
}
JobLaunchedLogItem::JobLaunchedLogItem(Job* job, status_t status)
:
AbstractJobLogItem(job),
fStatus(status)
{
}
JobLaunchedLogItem::~JobLaunchedLogItem()
{
}
LogItemType
JobLaunchedLogItem::Type() const
{
return kJobLaunched;
}
status_t
JobLaunchedLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Job \"%s\" launched: %s", fJob->Name(),
strerror(fStatus));
return B_OK;
}
status_t
JobLaunchedLogItem::GetParameter(BMessage& parameter) const
{
status_t status = AbstractJobLogItem::GetParameter(parameter);
if (status == B_OK)
status = parameter.AddInt32("status", fStatus);
return status;
}
JobTerminatedLogItem::JobTerminatedLogItem(Job* job, status_t status)
:
AbstractJobLogItem(job),
fStatus(status)
{
}
JobTerminatedLogItem::~JobTerminatedLogItem()
{
}
LogItemType
JobTerminatedLogItem::Type() const
{
return kJobTerminated;
}
status_t
JobTerminatedLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Job \"%s\" terminated: %s", fJob->Name(),
strerror(fStatus));
return B_OK;
}
status_t
JobTerminatedLogItem::GetParameter(BMessage& parameter) const
{
status_t status = AbstractJobLogItem::GetParameter(parameter);
if (status == B_OK)
status = parameter.AddInt32("status", fStatus);
return status;
}
JobEnabledLogItem::JobEnabledLogItem(Job* job, bool enabled)
:
AbstractJobLogItem(job),
fEnabled(enabled)
{
}
JobEnabledLogItem::~JobEnabledLogItem()
{
}
LogItemType
JobEnabledLogItem::Type() const
{
return kJobEnabled;
}
status_t
JobEnabledLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Job \"%s\" %sabled", fJob->Name(),
fEnabled ? "en" : "dis");
return B_OK;
}
status_t
JobEnabledLogItem::GetParameter(BMessage& parameter) const
{
status_t status = AbstractJobLogItem::GetParameter(parameter);
if (status == B_OK)
status = parameter.AddBool("enabled", fEnabled);
return status;
}
JobStoppedLogItem::JobStoppedLogItem(BaseJob* job, bool force)
:
AbstractJobLogItem(job),
fForce(force)
{
}
JobStoppedLogItem::~JobStoppedLogItem()
{
}
LogItemType
JobStoppedLogItem::Type() const
{
return kJobStopped;
}
status_t
JobStoppedLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Job \"%s\" %sstopped", fJob->Name(),
fForce ? "force " : "");
return B_OK;
}
status_t
JobStoppedLogItem::GetParameter(BMessage& parameter) const
{
status_t status = AbstractJobLogItem::GetParameter(parameter);
if (status == B_OK)
status = parameter.AddBool("force", fForce);
return status;
}
EventLogItem::EventLogItem(BaseJob* job, Event* event)
:
AbstractJobLogItem(job),
fEvent(event)
{
}
EventLogItem::~EventLogItem()
{
}
LogItemType
EventLogItem::Type() const
{
return kEvent;
}
status_t
EventLogItem::GetMessage(BString& target) const
{
target.SetToFormat("Event triggered \"%s\": \"%s\"", fJob->Name(),
fEvent->ToString().String());
return B_OK;
}
status_t
EventLogItem::GetParameter(BMessage& parameter) const
{
status_t status = AbstractJobLogItem::GetParameter(parameter);
if (status == B_OK)
status = parameter.AddString("event", fEvent->ToString());
return status;
}
bool
EventLogItem::Matches(const char* jobName, const char* eventName)
{
if (eventName != NULL && strstr(fEvent->ToString(), eventName) == NULL)
return false;
return AbstractJobLogItem::Matches(jobName, NULL);
}
AbstractExternalEventLogItem::AbstractExternalEventLogItem(const char* name)
:
fEventName(name)
{
}
AbstractExternalEventLogItem::~AbstractExternalEventLogItem()
{
}
status_t
AbstractExternalEventLogItem::GetParameter(BMessage& parameter) const
{
return parameter.AddString("event", fEventName);
}
bool
AbstractExternalEventLogItem::Matches(const char* jobName,
const char* eventName)
{
if (jobName == NULL && eventName == NULL)
return true;
if (eventName != NULL && strstr(fEventName.String(), eventName) != NULL)
return true;
return false;
}
ExternalEventLogItem::ExternalEventLogItem(const char* name)
:
AbstractExternalEventLogItem(name)
{
}
ExternalEventLogItem::~ExternalEventLogItem()
{
}
LogItemType
ExternalEventLogItem::Type() const
{
return kExternalEvent;
}
status_t
ExternalEventLogItem::GetMessage(BString& target) const
{
target.SetToFormat("External event triggered: \"%s\"",
fEventName.String());
return B_OK;
}
ExternalEventRegisteredLogItem::ExternalEventRegisteredLogItem(const char* name)
:
AbstractExternalEventLogItem(name)
{
}
ExternalEventRegisteredLogItem::~ExternalEventRegisteredLogItem()
{
}
LogItemType
ExternalEventRegisteredLogItem::Type() const
{
return kExternalEventRegistered;
}
status_t
ExternalEventRegisteredLogItem::GetMessage(BString& target) const
{
target.SetToFormat("External event registered: \"%s\"",
fEventName.String());
return B_OK;
}
ExternalEventUnregisteredLogItem::ExternalEventUnregisteredLogItem(
const char* name)
:
AbstractExternalEventLogItem(name)
{
}
ExternalEventUnregisteredLogItem::~ExternalEventUnregisteredLogItem()
{
}
LogItemType
ExternalEventUnregisteredLogItem::Type() const
{
return kExternalEventUnregistered;
}
status_t
ExternalEventUnregisteredLogItem::GetMessage(BString& target) const
{
target.SetToFormat("External event unregistered: \"%s\"",
fEventName.String());
return B_OK;
}