icingadb-web icon indicating copy to clipboard operation
icingadb-web copied to clipboard

Feature Request: Please give us back the timestamps in history view

Open Mordecaine opened this issue 1 year ago • 4 comments

In the monitoring module webinterface (the old web interface) you had timestamps in the history view. In the icingadb webinterface, It's really hard to debug thinks because of the relative time values: grafik

Please return to the good old timestamps: thumbnail_image001

I have some ideas: idea

Mordecaine avatar Sep 25 '24 13:09 Mordecaine

+1 The old timestamp format, displaying the exact time directly, is much more efficient for monitoring. With the current implementation, hovering over the date to get the precise time adds an unnecessary step. In critical situations, especially in monitoring environments, it’s crucial to have immediate visibility of both the date and time without additional interaction. Reverting to the old format would improve usability and speed in resolving issues.

mwester117 avatar Sep 26 '24 07:09 mwester117

If you are interested in a quick "hack" to format the history list the way you see fit: Add file /usr/share/icinga-php/ipl/vendor/ipl/web/src/Widget/TimeShortDT.php with the following content:

<?php

namespace ipl\Web\Widget;

use Icinga\Date\DateFormatter;
use ipl\Html\BaseHtmlElement;

class TimeShortDT extends BaseHtmlElement
{
    /** @var int */
    protected $timestamp;
    protected $tag = 'time';
    protected $defaultAttributes = ['class' => 'value'];

    public function __construct($timestamp)
    {
        $this->timestamp = (int) $timestamp;
    }

    protected function assemble()
    {
        $dateTime = DateFormatter::formatDateTime($this->timestamp);

        $this->addAttributes([
            'datetime' => $dateTime,
            'title'    => $dateTime
        ]);

        $this->add( date("j. M 'y H:i", $this->timestamp) );
    }
}

Then, apply this patch to /usr/share/icingaweb2/modules/icingadb/library/Icingadb/Widget/ItemList/BaseHistoryListItem.php

*** BaseHistoryListItem.php     2024-08-05 14:16:40.000000000 +0200
--- BaseHistoryListItem.php_new 2024-10-07 11:00:30.001129726 +0200
***************
*** 24,29 ****
--- 24,30 ----
  use ipl\Web\Widget\EmptyState;
  use ipl\Web\Widget\StateBall;
  use ipl\Web\Widget\TimeAgo;
+ use ipl\Web\Widget\TimeShortDT;
  use ipl\Html\BaseHtmlElement;
  use ipl\Html\HtmlElement;
  use ipl\Html\Text;
***************
*** 402,407 ****

      protected function createTimestamp(): ?BaseHtmlElement
      {
!         return new TimeAgo($this->item->event_time->getTimestamp());
      }
  }
--- 403,408 ----

      protected function createTimestamp(): ?BaseHtmlElement
      {
!         return new TimeShortDT($this->item->event_time->getTimestamp());
      }
  }

This will display the time as "10. Oct '24 19:11". You can change the format to whatever you prefer by changing the date format in the last statement of the file TimeShortDT.php.

Of course you need to apply this change whenever you update icingaweb.

Hope this helps...

alamp1360 avatar Oct 08 '24 17:10 alamp1360

@flourish86 Please add the latest mockups here as well

nilmerg avatar Feb 04 '25 11:02 nilmerg

An excerpt of a more wholistic concept for Event History redesign. For more detailed information see #1067 .

Group Event by day and add a separator per day to the list

  • A the visual break helps to get a better overview of, on which day the events occurred and avoids redundant information.
  • As the timestamps are on the right hand side of the list item, aligning the date to the right makes it easy to scan by time, while focussing on scanning for visuals on the left side

Image

Display absolute timestamps

Use absolute timestamps by default
  • While using absolute timestamps should be used by default since they allow for more precise contextual analysis, relative timestamps can be more helpful for analyzing only recent events (especially when the view is used as a dashlet)
  • Add an option for relative timestamps Screenshot 2024-09-26 at 17 46 36
Toggle relative timestamps: the fancy version 🪄

Notes

  1. This should not be implemented on its own without a proper hint, since the functionality is pretty undiscoverable for most users.
  2. It should also not solely be done in the frontend, since users need relative timestamps to work with urls to be used in dashboards
  3. The option should also be kept (similar to view modes), since users probably won't toggle every time, when they prefer the non-default version Screen Recording 2024-12-09 at 16 20 18

flourish86 avatar Feb 20 '25 08:02 flourish86

Can we please get that change in the near future? I like the idea from @flourish86 .

ngoeddel-openi avatar Aug 27 '25 15:08 ngoeddel-openi

Based on alamp1360's "hack" I have very good results with an "everything" variant:

        $this->add(new TimeAgo($this->timestamp));
        $this->add(": ");
        $this->add(date("D j M Y, H:i O", $this->timestamp));

It has (nearly) constant width (on the right) for easy scanning while scrolling, timezone information for the full timestamps and still provides the time delta for more recent events.

Having the time displayed together with the date is absolutely crucial for a history view, IMHO, especially if the timestamps might end up in screenshots.

(On mobile in vertical orientation with "minimal" listing it almost always results in only the icon + timestamp showing, but then again I find the minimal mode unusable on mobile with vertical orientation most times anyway since too many things end up being elided, in horizontal orientation it's fine, YMMV)

Image
Image

dreesknapp avatar Aug 28 '25 07:08 dreesknapp

@alamp1360 Hi. Since the file /usr/share/icingaweb2/modules/icingadb/library/Icingadb/Widget/ItemList/BaseHistoryListItem.php does not exist anymore, where can I change the timestamp on the latest version? Can you please help me with that?

ngoeddel-openi avatar Nov 04 '25 15:11 ngoeddel-openi

Here are the patches i use on the latest version of Icingaweb2 image:

Patch for file /usr/share/icingaweb2/modules/icingadb/library/Icingadb/View/NotificationRenderer.php:

*** NotificationRenderer.php_orig       2025-06-23 07:59:33.000000000 +0200
--- NotificationRenderer.php    2025-07-02 15:16:33.170054482 +0200
***************
*** 26,31 ****
--- 26,32 ----
  use ipl\Web\Widget\Link;
  use ipl\Web\Widget\StateBall;
  use ipl\Web\Widget\TimeAgo;
+ use ipl\Web\Widget\TimeShortDT;

  /** @implements ItemRenderer<NotificationHistory> */
  class NotificationRenderer implements ItemRenderer
***************
*** 153,159 ****

      public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): void
      {
!         $info->addHtml(new TimeAgo($item->send_time->getTimestamp()));
      }

      public function assembleFooter($item, HtmlDocument $footer, string $layout): void
--- 154,160 ----

      public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): void
      {
!         $info->addHtml(new TimeShortDT($item->send_time->getTimestamp()));
      }

      public function assembleFooter($item, HtmlDocument $footer, string $layout): void

Patch for file /usr/share/icingaweb2/modules/icingadb/library/Icingadb/View/EventRenderer.php:

*** EventRenderer.php_save      2025-07-02 15:09:36.000000000 +0200
--- EventRenderer.php   2025-07-02 15:11:50.423959159 +0200
***************
*** 29,34 ****
--- 29,35 ----
  use ipl\Web\Widget\Link;
  use ipl\Web\Widget\StateBall;
  use ipl\Web\Widget\TimeAgo;
+ use ipl\Web\Widget\TimeShortDT;

  /** @implements ItemRenderer<History> */
  class EventRenderer implements ItemRenderer
***************
*** 413,419 ****

      public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): void
      {
!         $info->addHtml(new TimeAgo($item->event_time->getTimestamp()));
      }

      public function assembleFooter($item, HtmlDocument $footer, string $layout): void
--- 414,420 ----

      public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): void
      {
!         $info->addHtml(new TimeShortDT($item->event_time->getTimestamp()));
      }

      public function assembleFooter($item, HtmlDocument $footer, string $layout): void

And the content of file TimeShortDT.php, which has to go to directory /usr/share/icinga-php/ipl/vendor/ipl/web/src/Widget/:

<?php

namespace ipl\Web\Widget;

use Icinga\Date\DateFormatter;
use ipl\Html\BaseHtmlElement;

class TimeShortDT extends BaseHtmlElement
{
    /** @var int */
    protected $timestamp;

    protected $tag = 'time';

    protected $defaultAttributes = ['class' => 'value'];

    public function __construct($timestamp)
    {
        $this->timestamp = (int) $timestamp;
    }

    protected function assemble()
    {
        $dateTime = DateFormatter::formatDateTime($this->timestamp);

        $this->addAttributes([
            'datetime' => $dateTime,
            'title'    => $dateTime
        ]);

        $this->add( date("j. M 'y H:i", $this->timestamp) );
    }
}

Greetings!

alamp1360 avatar Nov 05 '25 10:11 alamp1360

It's time to tackle this.

Considerations

Both changes are expected to work in all of the following views:

  • Host History
  • Service History
  • Notifications
  • Event Overview
Absolute/Relative Representation

This is also about the event overview. As such, we have to acknowledge its limitations with respect to database load/performance. So one thing immediately clear to me is: That's a client side update only. Interacting with this, be it the toggle in the top left or the time elements, must not reload the content!

Let's also not forget that the rendering on the backend for the list is the same as in an detail's header. At least for events and notifications. The interaction described above is not meant for those views. Header time elements must not be clickable and not be influenced by the toggle in the list.

So, with that being said, what does this entail?

Implementation

Frontend

Absolute/Relative Representation

At the moment, time elements already use the time tag and populate the datetime property with a standardized formatted string in the user's current timezone. This should be the basis for what Javascript uses to change between the various representations. Though, the current representation relies on a feature provided by Icinga Web: https://github.com/Icinga/icingaweb2/blob/70f29827f921f24b2afc0556c4800dfa55a2d0c1/public/js/icinga/ui.js#L484

I'd like to decouple it from Icinga Web and make it part of ipl-web instead. At least, the representation of the relative time. The used PHP widgets are already part of ipl-web. Though, this will be a different task.

Icinga DB Web will need to provide its own scripting to allow the user switch between relative and absolute time as well as rendering the absolute time according to the user's locale. Of course, it depends on what's responsible to render the relative representation, but that shouldn't block or rely on what happens as part of ipl-web.

The current behavior relies on the CSS classes time-ago, time-since and time-until. They're not referenced by any actual CSS rule as of now, so they can just be toggled to disable the current behavior. What the implementation in ipl-web will rely on isn't relevant yet and therefore … an implementation detail only.

What Icinga DB Web should be responsible for:

  • Handle the click on the time element to toggle the checkbox
  • Handle interaction with the toggle to change each time element's representation
    • Scripted (click on a time element) or manually
    • The current history state must be adjusted to reflect the toggle's state in the URL. Use icinga.history.replaceCurrentState() for this. (It requires an update to the container's icingaUrl data property. Note that this must be changed using jQuery, and not natively!)
    • The load more url must also be updated accordingly
    • The backend must be informed about the user's decision, as we expect it be stored in the session + preferences. A request in the background should perform this.
  • Render the absolute representation using Intl.DateTimeFormat(). The current locale is available as part of Icinga.config.locale. e.g. new Intl.DateTimeFormat("en", { timeStyle: "medium" }).format(new Date("2025-11-25 10:14:05")) (10:14:05 AM)

Backend

Absolute/Relative Representation

The backend should ensure the content already represents the user's chosen representation. The frontend should not be responsible to transform newly rendered content.

The backend uses three different states (in order) to choose the desired representation:

  1. Request parameter
  2. Session
  3. Preferences

To generate a localized absolute representation, IntlDateFormatter must be used. The current locale is available using Locale::getDefault().

Date Separation

\Icinga\Module\Icingadb\Widget\ItemList\LoadMoreObjectList is currently used in all four views. It should be renamed and extended to inject the separation elements similarly to the page separators.

Again, IntlDateFormatter must be used to render the date representation.

nilmerg avatar Nov 25 '25 11:11 nilmerg