0

With respect to versioning, the documentation for the Semantic Logging Application Block recommends:

If you do need to modify your EventSource class, you should restrict your changes to adding methods to support new log messages, and adding overloads of existing methods (that would have a new event ID). You should not delete or change the signature of existing methods.

Suppose I had the following EventSource class:

[EventSource(Name = "Instrumentation")]
public class InstrumentationEventSource : EventSource {
    private static readonly Lazy<InstrumentationEventSource> Singleton = new Lazy<InstrumentationEventSource>(() => new InstrumentationEventSource());

    public static InstrumentationEventSource Log { get { return Singleton.Value; } }

    private InstrumentationEventSource() {}

    [Event(eventId: 901)]
    public void EndPage(string url) {
        WriteEvent(901, url);
    }
}

And then I wanted to add support for logging a query string. Could I add an overloaded method with the same ID?

[Event(eventId: 901)]
public void EndPage(string url) {
    WriteEvent(901, url);
}

[Event(eventId: 901)]
public void EndPage(string url, string queryString) {
    WriteEvent(901, url, queryString);
}

How can I support future modifications with as little impact to applications or an out-of-process host logging application?

Could I keep the signatures simpler by making the additions in a model class?

public class LogData {
    public string url { get; set; }
    // public string queryString { get; set; }
}

and

[Event(eventId: 901)]
public void EndPage(LogData data) {
    WriteEvent(901, data);
    // Or does the params object[] args parameter not support classes?
    // WriteEvent(901, data.url);
    // And this would have to be changed anyway?
    // WriteEvent(901, data.url, data.queryString);
}

I'm not really sure where Event ID fits into it all, and how much the maintenance of the EventSource class needs to exert care over this.

maxwellb
  • 13,366
  • 2
  • 25
  • 35

1 Answers1

1

An EventSource presents your logging as structured data. In that sense, it is a formal published API.

And then I wanted to add support for logging a query string. Could I add an overloaded method with the same ID?

No. EventIds must be unique. However, if you just need to add new parameters to the method then as long as you add them at the end of the signature that is permissible (and bump the Event Version).

Could I keep the signatures simpler by making the additions in a model class?

No because the Event parameters must be primitive types (basically). A custom type such as LogData is unsupported.

Assuming you had:

[Event(eventId: 901)]
public void EndPage(string url) {
    WriteEvent(901, url);
}

and you wanted to add more information to that method then you could modify the existing method:

[Event(eventId: 901, Version = 1)]
public void EndPage(string url, string queryString) 
{
    WriteEvent(901, url, queryString);
}

If you didn't want that to affect existing callers you could give a default value for the parameter:

[Event(eventId: 901, Version = 1)]
public void EndPage(string url, string queryString = null) 
{
    WriteEvent(901, url, queryString);
}

Or you could provide a Non-event overload for the existing clients to use:

[NonEvent]
public void EndPage(string url) {
    this.EndPage(url, null);
}

[Event(eventId: 901, Version = 1)]
public void EndPage(string url, string queryString) 
{
    WriteEvent(901, url, queryString);
}
Randy Levy
  • 22,566
  • 4
  • 68
  • 94
  • Thank you. In your last example, am I adding the new method or replacing it (and updating all of my callers)? – maxwellb Jul 09 '15 at 12:09
  • Just modify the existing method...I've added some more details on how to avoid updating existing callers. – Randy Levy Jul 09 '15 at 15:30