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