I am going off the question here:
https://answers.splunk.com/answers/312914/httpeventcollectortracelistener-doesnt-flush.html
The user is adding his listener programmatically in code, e.g:
var listener = new HttpEventCollectorTraceListener(
new Uri(ConfigurationManager.AppSettings["SplunkUrl"], UriKind.Absolute),
ConfigurationManager.AppSettings["AppToken"]);
What I really want is to be able to add a listener in the config file attached to the binary -- could you light the way? Or is it not possible?
@mdufrasne it is technically possible to do this, but you will need a derived listener and the code is going to get a bit ugly. The reason is because our listener requires parameters to be passed via the constructor because we did not optimize toward the config file based approach. Please file a bug though in our repo, as we could look into making this work, though it will be some time before we got to it. You could also consider sending us a PR.
Here's how to do it yourself with the current listener. Basically you need to derive from our listener and add a default constructor. In your new listener add properties for all the parameters that would be passed via the constructor. The tricky part is the parameters in the ctor are then used to configure the internal HttpEventCollectorSender instance. You'll need to override this member using reflection APIs.
The next question is when to do that override as you cannot do it in the default constructor as the properties are not initialized yet.
One way to do it (cleaner but harder) is to override each of the methods in this region and have them check a flag which if not initialized, then overrides the sender. The check function needs a lock because multiple threads could be accessing the listener. Once the sender is overridden, then you can set the flag to true.
The alternative is to have each property override the sender as it is set, or add a dummy boolean property that when set to true overrides the sender. Then you set the property last in your config.
If it were me, I'd probably keep it simple and just go with the last option and use the dummy property.
As far as how to wire up the listener itself in config, you have to specify the type and assembly as is mentioned in this SO post.
Let me know if any of this makes sense 😛
@mdufrasne it is technically possible to do this, but you will need a derived listener and the code is going to get a bit ugly. The reason is because our listener requires parameters to be passed via the constructor because we did not optimize toward the config file based approach. Please file a bug though in our repo, as we could look into making this work, though it will be some time before we got to it. You could also consider sending us a PR.
Here's how to do it yourself with the current listener. Basically you need to derive from our listener and add a default constructor. In your new listener add properties for all the parameters that would be passed via the constructor. The tricky part is the parameters in the ctor are then used to configure the internal HttpEventCollectorSender instance. You'll need to override this member using reflection APIs.
The next question is when to do that override as you cannot do it in the default constructor as the properties are not initialized yet.
One way to do it (cleaner but harder) is to override each of the methods in this region and have them check a flag which if not initialized, then overrides the sender. The check function needs a lock because multiple threads could be accessing the listener. Once the sender is overridden, then you can set the flag to true.
The alternative is to have each property override the sender as it is set, or add a dummy boolean property that when set to true overrides the sender. Then you set the property last in your config.
If it were me, I'd probably keep it simple and just go with the last option and use the dummy property.
As far as how to wire up the listener itself in config, you have to specify the type and assembly as is mentioned in this SO post.
Let me know if any of this makes sense 😛
In terms of @jkat54's point it is more secure to not store your authentication information within a config file. When you do there is the concern that someone access the file or you accidentally share that file and put it in a Github repo somewhere etc which then exposes credentials. In this case HEC creds will only allow sending data so you will not be exposing Splunk login credentials, but it is still a potential vulnerability.
One way to mitigate this is to encypt the Token using the DPAPI and then decrypt when you read it.
Are you serious? You can put code in a .config file?
I never said anything about putting code in a conf file. We are talking about how to wire up an assembly in a config file.
Not sure how you got that from the question 🙂 everytime I open my mouth here though... Every time!!!
🙂
You said "Are you serious? You can put code in a .config file?"
What did you mean by this / why did you ask this question?
That's what I thought the op was asking.
"What I really want is to be able to add a listener in the config file attached to the binary".
To me that meant, how do I put listener code in my config file. Obviously I'm still a newb at .net as it was obvious to you.
Ahh I see. Well I agree with you that putting the code for the listener in the config file is a bad idea even if you could.
Using config files to load custom listeners (that are defined outside in assemblies) is not uncommon though.
Your point on credentials is definitely important so thanks for pointing that out.
Apologies on any confusion.....
Ha ha I deleted my answer because it was so far off. I'm glad you showed up and gracefully let me down from my high chair though
😉
No apology needed. I'm happy to learn!
It's all good!
Oh and my question was legitimate not a tongue in cheek or anything.