Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tag enhancement #12

Open
wants to merge 21 commits into
base: dev
Choose a base branch
from
Open

Conversation

MattMofDoom
Copy link
Contributor

This pull will resolve and close #11

This pull can supersede and close #10 - it includes the added logging and OpsGenie properties that this pull request added

The System.Text.Json dependency was updated for this request.

@MattMofDoom
Copy link
Contributor Author

@nblumhardt I've closed #9 and #10 as this PR supersedes them.

This PR will resolve #11 while adding better logging, adding the Seq event properties to the Opsgenie alert, and implementing a suppression setting.

Copy link
Member

@nblumhardt nblumhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @MattMofDoom! Ran through quickly; a few interlocking changes in this PR, I think I covered them all but might be easier and faster to review as small/individual/focused PRs next time around :-) .. Let me know if I've misread anything. Cheers!


// ReSharper disable ClassNeverInstantiated.Global

namespace Seq.App.Opsgenie.Classes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Organizing into Classes and Interfaces might not give as much insight into the structure of the codebase as some alternatives - could this one go in Seq.App.Opsgenie.Api, perhaps, since the structure of these types (presumably) matches the requirements of the Opsgenie API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah should be fine. I'll take a look.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reorganised into Api and Client


namespace Seq.App.Opsgenie.Interfaces
{
interface IOpsgenieApiClient
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one might go in Seq.App.Opsgenie.Client?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reorganised into Api and Client

@@ -6,15 +6,15 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Seq.Apps;
using Seq.App.Opsgenie.Classes;
using Seq.App.Opsgenie.Interfaces;

namespace Seq.App.Opsgenie
{
class OpsgenieApiClient : IOpsgenieApiClient, IDisposable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type could also move to Seq.App.Opsgenie.Client

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reorganised into Api and Client

if (!response.IsSuccessStatusCode)
result.Response = opsGenieResponse;
}
catch (Exception ex)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to just let the exception bubble up, here, and be handled by the hosting environment? In general, Seq apps shouldn't customize error handling, since the app host does this consistently for all hosted apps and in future we might make improvements up at that layer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the perspective was to allow a consistent approach to error handling based on a signal targeted to the specific appid or appinstanceid (or instance name) that included the context/properties around what the alert was. So for example if we fail to connect to OpsGenie to send the alert, we can send an email or Teams or JIRA alert that preserves the context of what we were alerting, by having an error event that preserves this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still inclined to have this caught for the reasons above. It's fairly serious if an alert doesn't go, and if we can catch what the alert was, then we have opportunity to send an alert via other alerting apps. Overall this speaks to Seq reliability - being able to do fallbacks etc. Unfortunately the hosting environment doesn't preserve the event data ... I suppose it could still throw after this?

HelpText =
"If an alert has been raised, further alerts will be suppressed for this time. Default 60, Minimum 0.",
InputType = SettingInputType.Integer)]
public int SuppressionTime { get; set; } = 60;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppression time is provided by Seq (for regular alerts it's called suppression time; for streamed events its "debounce window"), it'd be preferable not to duplicate it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed suppression time


var alert = new OpsgenieAlert(
message,
evt.Id,
description,
priority.ToString(),
responders,
new Dictionary<string, string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This info should generally come from the event directly; e.g. based on the event type, events carry the URL that the user can navigate to in order to see relevant info. There are three branches in:

https://github.com/datalust/seq-app-htmlemail/blob/dev/src/Seq.App.EmailPlus/Resources/DefaultBodyTemplate.html#L105

based on the event type.

Alerts carry different data from regular events; the template shows some of this.

The Slack app has some helper types to achieve something along the lines of what you'll need in order to add this feature here:

https://github.com/bytenik/Seq.App.Slack/tree/master/src/Seq.App.Slack/Messages

Could be nice to bring into this codebase (but rather than as a "formatter", perhaps as "payload builders")? Seems deep enough to need a separate PR :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, can't recall if this was before I was across the alerting changes or not. It's useful to have the data show up in Opsgenie so I'll take a look at the slack helpers to start with

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure how to proceed with this. It looks like only NameSpacedAlertTitle and event URL would be affected? I think the latter would also have to be amended in the HandlebarsTemplate.

Overall the goal would be to include the raw seq properties in the OpsGenieAlert, which makes this a more informative alert when examining in OpsGenie. Tested when I had access to Opsgenie but a bit harder to visualise now.


var message = _generateMessage.Render(evt);
var description = _generateDescription.Render(evt);
var priority = ComputePriority(evt);
var tags = ComputeTags(evt);
var tags = ComputeTags(evt, _includeTags, _includeTagProperty, _tags);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance of an example (screenshot of config?) showing how tag configuration would work in practice with this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I should be able to dig it up. The difference was that it was not handling a comma delimited string passed from a Seq alert, because it was always expecting an array. This allows either to work as expected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nblumhardt An example is shown below.

If I configure the Notification property tags on an alert, the current (v1.0) version of Seq.App.OpsGenie will ignore the comma-delimited tags sent from the alert, and only send the configured tags on the app instance.

With the enhancement, my comma-delimited set of tags will be used, although I'm not sure that the configured app instance tags are being included (it should be combining the OpsGenie alert tags with the event tags), and the whole set of tags isn't being logged - I'll have to check that.

Alert config:
image

OpsGenie instance tags config:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nblumhardt This is a bit curious. The unit tests for tag calculation work correctly - if a static tag is configured in the OpsGenie instance and an event passes a comma-delimited set of tags, it correctly combines the static tag with the event tags.

However in the DEV instance, thanks to the Handlebars template I'm using, I can see in the Opsgenie alert that Tags was passed from the alert and shows within the alert description, but doesn't actually get passed to OpsGenie as a Tags property. The static tag ("Test") does get passed and this is seen in the Seq logging as well.

Handlebars template is
<p>{{AppName}} failed with the error {{Description}}<br /><br /></p><table>{{#each $Properties}}<tr><td><b>{{@key}}:</b></td><td>{{this}}</td></tr>{{/each}}</table><p>Alert created by Seq</p>

and the outcome in OpsGenie is below. You can see the tag ("Test") just below the title, but you can see in the description that the Handlebars template has shown the Tags property from the event passed by Alerting.

image

Suggests a problem in the ComputeTags method, but I don't see it - can't reproduce with a test case that emulates what gets passed. This is complicated by the fact that I'm leaving my current job so won't have access to their OpsGenie for testing in future ☹️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nblumhardt I've amended the test case to evaluate a calculated OpsgenieAlert, for passing either an array or a comma separated value, and I do think it's working as intended. I don't know what I was seeing on the OpsGenie side, but at the end of the day, if the calculated OpsGenieAlert has the tags, they will be passed to Opsgenie.

src/Seq.App.Opsgenie/Seq.App.Opsgenie.csproj Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Comma-delimited strings are not parsed when received via the event tag property
2 participants