|
1 | 1 | <script lang="ts" setup>
|
2 |
| -import { ref, onMounted, computed } from 'vue' |
| 2 | +import { ref } from 'vue' |
3 | 3 | import { useHead } from '@vueuse/head'
|
4 | 4 | import { Line, Doughnut } from 'vue-chartjs'
|
5 | 5 | import {
|
@@ -167,24 +167,24 @@ const cache = ref<Cache>({
|
167 | 167 | const slowQueries = ref<SlowQuery[]>([
|
168 | 168 | {
|
169 | 169 | query: "insert into `tickets` (`flight_id`, `user_id`, `price`, `created_at`, `updated_at`) values (?, ?, ?, ?, ?)",
|
170 |
| - location: "app/Http/Controllers/FlightTicketController.php:26", |
| 170 | + location: "app/Actions/FlightAction.ts:26", |
171 | 171 | count: 347,
|
172 | 172 | slowest: 3099,
|
173 | 173 | },
|
174 | 174 | {
|
175 | 175 | query: "select `id`, `departs_at` from `flights` where `departs_at` > ? order by `departs_at` asc",
|
176 |
| - location: "app/Http/Controllers/FlightController.php:91", |
| 176 | + location: "app/Actions/FlightAction.ts:91", |
177 | 177 | count: 363,
|
178 | 178 | slowest: 3088,
|
179 | 179 | },
|
180 | 180 | ])
|
181 | 181 |
|
182 | 182 | const users = ref<User[]>([
|
183 |
| - { name: 'Joe Dixon', email: 'joe@laravel.com', requests: 68 }, |
184 |
| - { name: 'Tim MacDonald', email: 'tim@laravel.com', requests: 65 }, |
185 |
| - { name: 'Christoph Rumpel', email: 'christoph@laravel.com', requests: 51 }, |
186 |
| - { name: 'James Brooks', email: 'james@laravel.com', requests: 50 }, |
187 |
| - { name: 'Guus Leeuw', email: 'guus@laravel.com', requests: 47 }, |
| 183 | + { name: 'Chris Breuer', email: 'chris@stacksjs.org', requests: 68 }, |
| 184 | + { name: 'Avery', email: 'avery@stacksjs.org', requests: 65 }, |
| 185 | + { name: 'Michael', email: 'michael@stacksjs.org', requests: 51 }, |
| 186 | + { name: 'Glenn', email: 'glenn@stacksjs.org', requests: 50 }, |
| 187 | + { name: 'Zoltan', email: 'zoltan@stacksjs.org', requests: 47 }, |
188 | 188 | ])
|
189 | 189 |
|
190 | 190 | // Chart data
|
@@ -515,72 +515,82 @@ const statsCards = [
|
515 | 515 | </div>
|
516 | 516 | </div>
|
517 | 517 |
|
518 |
| - <!-- Queue Monitoring --> |
| 518 | + <!-- Queue Monitoring & Cache Performance --> |
519 | 519 | <div class="mt-8 px-4 lg:px-8 sm:px-6">
|
520 |
| - <div class="sm:flex sm:items-center"> |
521 |
| - <div class="sm:flex-auto"> |
522 |
| - <h1 class="text-base text-gray-900 dark:text-gray-100 font-semibold leading-6"> |
523 |
| - Queue Monitoring |
524 |
| - </h1> |
525 |
| - <p class="mt-2 text-sm text-gray-700 dark:text-gray-300"> |
526 |
| - Real-time monitoring of your application's queue processing. |
527 |
| - </p> |
528 |
| - </div> |
529 |
| - </div> |
530 |
| - |
531 |
| - <div class="mt-8 grid grid-cols-1 gap-6 lg:grid-cols-2"> |
532 |
| - <!-- Queues --> |
533 |
| - <div class="overflow-hidden rounded-lg bg-white dark:bg-blue-gray-700 shadow"> |
534 |
| - <div class="p-6"> |
535 |
| - <div class="space-y-8"> |
536 |
| - <!-- Queue Stats --> |
537 |
| - <div v-for="(stats, name) in queues" :key="name" class="space-y-4"> |
538 |
| - <div> |
539 |
| - <h4 class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ name }}</h4> |
540 |
| - </div> |
541 |
| - |
542 |
| - <!-- Status Pills --> |
543 |
| - <div class="flex items-center space-x-2"> |
544 |
| - <div v-for="(value, status) in stats" :key="status" |
545 |
| - class="inline-flex items-center space-x-1" |
546 |
| - :class="{ |
547 |
| - 'text-blue-700 dark:text-blue-300': status === 'queued', |
548 |
| - 'text-yellow-700 dark:text-yellow-300': status === 'processing', |
549 |
| - 'text-green-700 dark:text-green-300': status === 'processed', |
550 |
| - 'text-purple-700 dark:text-purple-300': status === 'released', |
551 |
| - 'text-red-700 dark:text-red-300': status === 'failed' |
552 |
| - }"> |
553 |
| - <div :class="[getQueueStatusColor(status), 'h-1.5 w-1.5 rounded-full']"></div> |
554 |
| - <span class="text-xs font-mono">{{ value }}</span> |
555 |
| - </div> |
556 |
| - </div> |
| 520 | + <div class="grid grid-cols-1 gap-6 lg:grid-cols-2"> |
| 521 | + <!-- Queue Monitoring --> |
| 522 | + <div> |
| 523 | + <div class="sm:flex sm:items-center"> |
| 524 | + <div class="sm:flex-auto"> |
| 525 | + <h1 class="text-base text-gray-900 dark:text-gray-100 font-semibold leading-6"> |
| 526 | + Queue Monitoring |
| 527 | + </h1> |
| 528 | + <p class="mt-2 text-sm text-gray-700 dark:text-gray-300"> |
| 529 | + Real-time monitoring of your application's queue processing. |
| 530 | + </p> |
| 531 | + </div> |
| 532 | + </div> |
557 | 533 |
|
558 |
| - <!-- Queue Chart --> |
559 |
| - <div> |
560 |
| - <div class="flex items-center space-x-4 mb-2"> |
| 534 | + <div class="mt-8 overflow-hidden rounded-lg bg-white dark:bg-blue-gray-700 shadow"> |
| 535 | + <div class="p-6"> |
| 536 | + <div class="space-y-8"> |
| 537 | + <!-- Queue Stats --> |
| 538 | + <div v-for="(stats, name) in queues" :key="name" class="space-y-4"> |
| 539 | + <div class="flex items-center justify-between"> |
561 | 540 | <div class="flex items-center space-x-2">
|
562 |
| - <div class="h-1 w-4 bg-green-500 rounded"></div> |
563 |
| - <span class="text-xs font-medium text-gray-500 dark:text-gray-400">Processed</span> |
| 541 | + <h4 class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-blue-gray-600 dark:text-gray-200"> |
| 542 | + {{ name }} |
| 543 | + </h4> |
564 | 544 | </div>
|
565 |
| - <div class="flex items-center space-x-2"> |
566 |
| - <div class="h-1 w-4 bg-red-500 rounded"></div> |
567 |
| - <span class="text-xs font-medium text-gray-500 dark:text-gray-400">Failed</span> |
| 545 | + <div class="flex items-center space-x-3"> |
| 546 | + <div v-for="(value, status) in stats" :key="status" |
| 547 | + class="group relative"> |
| 548 | + <div class="flex items-center space-x-2 cursor-help" |
| 549 | + :class="{ |
| 550 | + 'text-blue-700 dark:text-blue-300': status === 'queued', |
| 551 | + 'text-yellow-700 dark:text-yellow-300': status === 'processing', |
| 552 | + 'text-green-700 dark:text-green-300': status === 'processed', |
| 553 | + 'text-purple-700 dark:text-purple-300': status === 'released', |
| 554 | + 'text-red-700 dark:text-red-300': status === 'failed' |
| 555 | + }"> |
| 556 | + <div :class="[getQueueStatusColor(status), 'h-2.5 w-2.5 rounded-full']"></div> |
| 557 | + <span class="text-xs font-mono">{{ value }}</span> |
| 558 | + </div> |
| 559 | + <div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 hidden group-hover:block z-10"> |
| 560 | + <div class="relative"> |
| 561 | + <div class="px-2 py-1 text-xs font-medium text-white bg-gray-900 dark:bg-gray-700 rounded shadow-lg whitespace-nowrap"> |
| 562 | + {{ status.charAt(0).toUpperCase() + status.slice(1) }} Jobs |
| 563 | + </div> |
| 564 | + <div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-gray-900 dark:border-t-gray-700"></div> |
| 565 | + </div> |
| 566 | + </div> |
| 567 | + </div> |
568 | 568 | </div>
|
569 | 569 | </div>
|
570 |
| - <div class="h-48"> |
571 |
| - <Line :data="getQueueData(name)" :options="queueChartOptions" /> |
572 |
| - </div> |
573 |
| - <div class="flex justify-between text-xs font-mono text-gray-500 dark:text-gray-400 mt-2"> |
574 |
| - <span>12am</span> |
575 |
| - <span>6am</span> |
| 570 | + |
| 571 | + <!-- Queue Chart --> |
| 572 | + <div> |
| 573 | + <div class="flex items-center space-x-4 mb-2"> |
| 574 | + <div class="flex items-center space-x-2"> |
| 575 | + <div class="h-1 w-4 bg-green-500 rounded"></div> |
| 576 | + <span class="text-xs font-medium text-gray-500 dark:text-gray-400">Processed</span> |
| 577 | + </div> |
| 578 | + <div class="flex items-center space-x-2"> |
| 579 | + <div class="h-1 w-4 bg-red-500 rounded"></div> |
| 580 | + <span class="text-xs font-medium text-gray-500 dark:text-gray-400">Failed</span> |
| 581 | + </div> |
| 582 | + </div> |
| 583 | + <div class="h-48"> |
| 584 | + <Line :data="getQueueData(name)" :options="queueChartOptions" /> |
| 585 | + </div> |
576 | 586 | </div>
|
577 | 587 | </div>
|
578 | 588 | </div>
|
579 | 589 | </div>
|
580 | 590 | </div>
|
581 | 591 | </div>
|
582 | 592 |
|
583 |
| - <!-- Cache Stats --> |
| 593 | + <!-- Cache Performance --> |
584 | 594 | <div>
|
585 | 595 | <div class="sm:flex sm:items-center">
|
586 | 596 | <div class="sm:flex-auto">
|
@@ -660,54 +670,88 @@ const statsCards = [
|
660 | 670 | <div class="mt-8 px-4 lg:px-8 sm:px-6">
|
661 | 671 | <div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
662 | 672 | <!-- Exceptions -->
|
663 |
| - <div class="overflow-hidden rounded-lg bg-white dark:bg-blue-gray-700 shadow"> |
664 |
| - <div class="p-6"> |
665 |
| - <h3 class="text-base font-semibold text-gray-900 dark:text-gray-100">Exceptions</h3> |
666 |
| - <div class="mt-6 space-y-4"> |
667 |
| - <div v-for="exception in exceptions" :key="exception.type" class="space-y-2"> |
668 |
| - <div class="flex items-center justify-between"> |
669 |
| - <div> |
670 |
| - <p class="text-sm font-mono font-medium text-gray-900 dark:text-gray-100">{{ exception.type }}</p> |
671 |
| - <p class="text-xs font-mono text-gray-500 dark:text-gray-400">{{ exception.location }}</p> |
| 673 | + <div> |
| 674 | + <div class="sm:flex sm:items-center"> |
| 675 | + <div class="sm:flex-auto"> |
| 676 | + <h1 class="text-base text-gray-900 dark:text-gray-100 font-semibold leading-6"> |
| 677 | + Exceptions |
| 678 | + </h1> |
| 679 | + <p class="mt-2 text-sm text-gray-700 dark:text-gray-300"> |
| 680 | + Recent application exceptions and their occurrence rates. |
| 681 | + </p> |
| 682 | + </div> |
| 683 | + </div> |
| 684 | + |
| 685 | + <div class="mt-8 overflow-hidden rounded-lg bg-white dark:bg-blue-gray-700 shadow"> |
| 686 | + <div class="p-6"> |
| 687 | + <div class="space-y-4"> |
| 688 | + <div v-for="exception in exceptions" :key="exception.type" |
| 689 | + class="group relative rounded-lg border border-gray-200 dark:border-blue-gray-600 p-4 hover:border-blue-500 dark:hover:border-blue-400 transition-colors duration-150"> |
| 690 | + <div class="mb-3"> |
| 691 | + <div class="font-mono text-sm text-gray-900 dark:text-gray-100 leading-relaxed break-all"> |
| 692 | + {{ exception.type }} |
| 693 | + </div> |
672 | 694 | </div>
|
673 |
| - <div class="text-right"> |
674 |
| - <p class="text-sm font-mono font-medium text-gray-900 dark:text-gray-100">{{ exception.count }}</p> |
675 |
| - <p class="text-xs text-gray-500 dark:text-gray-400">{{ exception.latest }}</p> |
| 695 | + <div class="flex items-center justify-between text-sm border-t border-gray-100 dark:border-blue-gray-600 pt-3"> |
| 696 | + <div class="flex items-center space-x-2"> |
| 697 | + <div class="i-heroicons-code-bracket-square h-4 w-4 text-gray-400" /> |
| 698 | + <span class="font-mono text-gray-500 dark:text-gray-400">{{ exception.location }}</span> |
| 699 | + </div> |
| 700 | + <div class="flex items-center space-x-4"> |
| 701 | + <div class="flex items-center space-x-1"> |
| 702 | + <div class="i-heroicons-clock h-4 w-4 text-gray-400" /> |
| 703 | + <span class="font-mono text-gray-500 dark:text-gray-400">{{ exception.latest }}</span> |
| 704 | + </div> |
| 705 | + <div class="flex items-center space-x-1"> |
| 706 | + <div class="i-heroicons-bolt h-4 w-4 text-gray-400" /> |
| 707 | + <span class="font-mono text-gray-500 dark:text-gray-400">{{ exception.count }}</span> |
| 708 | + </div> |
| 709 | + </div> |
676 | 710 | </div>
|
677 |
| - </div> |
678 |
| - <div class="h-1 w-full rounded-full bg-gray-200 dark:bg-blue-gray-600"> |
679 |
| - <div class="h-1 rounded-full bg-red-500" style="width: 75%"></div> |
| 711 | + <div class="absolute left-0 top-0 w-1 h-full bg-red-500 rounded-l-lg"></div> |
680 | 712 | </div>
|
681 | 713 | </div>
|
682 | 714 | </div>
|
683 | 715 | </div>
|
684 | 716 | </div>
|
685 | 717 |
|
686 | 718 | <!-- Slow Queries -->
|
687 |
| - <div class="overflow-hidden rounded-lg bg-white dark:bg-blue-gray-700 shadow"> |
688 |
| - <div class="p-6"> |
689 |
| - <h3 class="text-base font-semibold text-gray-900 dark:text-gray-100">Slow Queries</h3> |
690 |
| - <div class="mt-6 space-y-4"> |
691 |
| - <div v-for="query in slowQueries" :key="query.location" |
692 |
| - class="group rounded-lg border border-gray-200 dark:border-blue-gray-600 p-4 hover:border-blue-500 dark:hover:border-blue-400 transition-colors duration-150"> |
693 |
| - <div class="mb-3"> |
694 |
| - <div class="font-mono text-sm text-gray-900 dark:text-gray-100 leading-relaxed break-all"> |
695 |
| - {{ query.query }} |
696 |
| - </div> |
697 |
| - </div> |
698 |
| - <div class="flex items-center justify-between text-sm border-t border-gray-100 dark:border-blue-gray-600 pt-3"> |
699 |
| - <div class="flex items-center space-x-2"> |
700 |
| - <div class="i-heroicons-code-bracket-square h-4 w-4 text-gray-400" /> |
701 |
| - <span class="font-mono text-gray-500 dark:text-gray-400">{{ query.location }}</span> |
| 719 | + <div> |
| 720 | + <div class="sm:flex sm:items-center"> |
| 721 | + <div class="sm:flex-auto"> |
| 722 | + <h1 class="text-base text-gray-900 dark:text-gray-100 font-semibold leading-6"> |
| 723 | + Slow Queries |
| 724 | + </h1> |
| 725 | + <p class="mt-2 text-sm text-gray-700 dark:text-gray-300"> |
| 726 | + Database queries that are taking longer than expected to execute. |
| 727 | + </p> |
| 728 | + </div> |
| 729 | + </div> |
| 730 | + |
| 731 | + <div class="mt-8 overflow-hidden rounded-lg bg-white dark:bg-blue-gray-700 shadow"> |
| 732 | + <div class="p-6"> |
| 733 | + <div class="space-y-4"> |
| 734 | + <div v-for="query in slowQueries" :key="query.location" |
| 735 | + class="group rounded-lg border border-gray-200 dark:border-blue-gray-600 p-4 hover:border-blue-500 dark:hover:border-blue-400 transition-colors duration-150"> |
| 736 | + <div class="mb-3"> |
| 737 | + <div class="font-mono text-sm text-gray-900 dark:text-gray-100 leading-relaxed break-all"> |
| 738 | + {{ query.query }} |
| 739 | + </div> |
702 | 740 | </div>
|
703 |
| - <div class="flex items-center space-x-4"> |
704 |
| - <div class="flex items-center space-x-1"> |
705 |
| - <div class="i-heroicons-clock h-4 w-4 text-gray-400" /> |
706 |
| - <span class="font-mono text-gray-500 dark:text-gray-400">{{ query.count }}</span> |
| 741 | + <div class="flex items-center justify-between text-sm border-t border-gray-100 dark:border-blue-gray-600 pt-3"> |
| 742 | + <div class="flex items-center space-x-2"> |
| 743 | + <div class="i-heroicons-code-bracket-square h-4 w-4 text-gray-400" /> |
| 744 | + <span class="font-mono text-gray-500 dark:text-gray-400">{{ query.location }}</span> |
707 | 745 | </div>
|
708 |
| - <div class="flex items-center space-x-1"> |
709 |
| - <div class="i-heroicons-bolt h-4 w-4 text-gray-400" /> |
710 |
| - <span class="font-mono text-gray-500 dark:text-gray-400">{{ query.slowest }}ms</span> |
| 746 | + <div class="flex items-center space-x-4"> |
| 747 | + <div class="flex items-center space-x-1"> |
| 748 | + <div class="i-heroicons-clock h-4 w-4 text-gray-400" /> |
| 749 | + <span class="font-mono text-gray-500 dark:text-gray-400">{{ query.count }}</span> |
| 750 | + </div> |
| 751 | + <div class="flex items-center space-x-1"> |
| 752 | + <div class="i-heroicons-bolt h-4 w-4 text-gray-400" /> |
| 753 | + <span class="font-mono text-gray-500 dark:text-gray-400">{{ query.slowest }}ms</span> |
| 754 | + </div> |
711 | 755 | </div>
|
712 | 756 | </div>
|
713 | 757 | </div>
|
|
0 commit comments