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