Hangfire icon indicating copy to clipboard operation
Hangfire copied to clipboard

Improve display of job result and properties

Open 0xced opened this issue 6 years ago • 8 comments

It's quite common that job properties and/or result are strings. Since everything is serialized as JSON in the database, a string becomes quoted and has escaped characters. For displaying in the dashboard, it's nicer without the quotes and escaped characters.

Before: Before

After: After

0xced avatar Sep 13 '19 15:09 0xced

Ping.

0xced avatar Nov 18 '19 20:11 0xced

@odinserj Do you have any plan to merge this?

0xced avatar Feb 24 '20 21:02 0xced

Ping @odinserj.

0xced avatar Apr 23 '20 21:04 0xced

Freshly rebased onto master in case there's interest in merging this pull request.

0xced avatar Jun 12 '20 08:06 0xced

I just rebased on master. Is there a chance to see this merged @odinserj or @pieceofsummer?

0xced avatar Oct 08 '20 14:10 0xced

Rebased again on master. Still crossing my fingers that this pull request might get some attention. 🤞

0xced avatar Jan 27 '21 15:01 0xced

Freshly rebased on the dev branch, still crossing my fingers that this might get some attention. Ping @odinserj.

The failing test on AppVeyor (Ubuntu only, passes on Windows) seems completely unrelated to this pull request:

Failed Hangfire.SqlServer.Tests.SqlServerTimeoutJobFacts.Timer_UpdatesFetchedAtColumn(useMicrosoftDataSqlClient: False) [10 s]
  Error Message:
   Assert.Equal() Failure
Expected: 2022-02-01T13:31:25.3700000
Actual:   2022-02-01T13:31:27.3700000

0xced avatar Feb 03 '22 16:02 0xced

Thanks @0xced, I will check this before releasing 1.8 next month!

odinserj avatar Feb 04 '22 07:02 odinserj

Hello @0xced!

With Hangfire 1.8.0-rc3 it is possible to register custom widgets on the Job Details page, so the feature requested in this PR can be implemented in the following way:

.UseJobDetailsRenderer(10, dto =>
{
    var succeededState = dto.JobDetails.History
        .FirstOrDefault(x => x.StateName == SucceededState.StateName);

    if (succeededState != null && succeededState.Data.TryGetValue("Result", out var result))
    {
        var builder = new StringBuilder();
        builder.Append("<h3>Last Result</h3>");
        builder.Append("<pre><code>");
        builder.Append(WebUtility.HtmlEncode(SerializationHelper
            .Deserialize<string>(result, SerializationOption.User)
            .Replace("\n", "<br/>")));
        builder.Append("</code></pre>");
        return new NonEscapedString(builder.ToString());
    }

    return null;
})

This gives the following results without changing anything in Hangfire itself and allows more features to be implemented:

image

I think we can close this PR now, what do you think?

odinserj avatar Apr 20 '23 05:04 odinserj

Thank you, it works fine for rendering the state history. I don't actually need to add a widget, I just want to remove the useless quotes on the Result. I was able to achieve this goal with a custom renderer that only alters the history:

.UseJobDetailsRenderer(10, dto =>
{
    foreach (var history in dto.JobDetails.History.Where(e => e.StateName == SucceededState.StateName))
    {
        if (history.Data.TryGetValue("Result", out var result))
        {
            history.Data["Result"] = result.Trim('"');
        }
    }

    return null;
});

Unfortunately, this callback is called after the parameters are rendered so modifying dto.JobDetails.Properties has no effect. We can't trim or otherwise modify how the parameters are rendered by altering the JobDetailsRendererDto. 😞

Is there an alternative solution to tweak the job parameters?

0xced avatar Jun 05 '23 11:06 0xced