Using .Net Core 3.1
I've implemented my event source like this:
[EventSource(Name = "RequestStatistics-Events")]
public sealed class RequestEventsProvider : EventSource
{
public RequestEventsProvider() : base(throwOnEventWriteErrors: false)
{
}
[Event(1, Level = EventLevel.Informational, Opcode = EventOpcode.Info)]
public void RequestProcessed(string requestPath, int responseCode, long processingTime)
{
WriteEvent(1, requestPath, responseCode, processingTime);
}
}
Then I collect tracing with dotnet-trace like this:
dotnet-trace collect --providers RequestStatistics-Events -p 23544
Then I open tracelog in PerfView and see my events:
As you can see every event contains stack within. It creates additional overhead though it is absolutely useless in my scenario. How can I disable stack collection?
Another question is: is it possible to disable stacks for Microsoft-Diagnostics-DiagnosticSource provider? I saw something like this in PerfView logs:
Enabling Provider:Microsoft-Diagnostics-DiagnosticSource Level:Informational Keywords:0xfffffffffffff7ff Stacks:1 Values:...blabla...
and I,ve tried to run collection with "stacks" key-value pair:
Microsoft-Diagnostics-DiagnosticSource:0xfffffffffffff7ff:4:Stacks=0
but it didn't affect anything.
i'm trying to test the DependencyService of my app by displaying an alert dialog from an android project when i press a button i created in the share code project.
When i try to set the Context property in the 'AlertDialog.Builder' by entering 'this' in the parenthesis i get this error: "Cannot convert from 'CallDiverter2.Droid.CallDiverter_Android' to 'Android.Content.Context'.
Also the namespace is decorated with: '[assembly: Dependency(typeof(CallDiverter_Android))]' if its matter.
this is the function in the android project i want to call using the DependecyService:
public class CallDiverter_Android : ICallDiverter
{
public void DivertCall(string callForwardString)
{
//Divert call code
//String callForwardString = "**21*1234567890#";
//Intent callIntent = new Intent(Intent.ActionDial); // ACTION_CALL
//Android.Net.Uri uri = Android.Net.Uri.Parse(callForwardString);
//callIntent.SetData(uri);
//Android.App.Application.Context.StartActivity(callIntent);
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
AlertDialog alert = dialog.Create();
alert.SetTitle("Title");
alert.SetMessage("Simple Alert");
alert.SetButton("OK", (s, ev) =>
{
alert.SetMessage("This is an alert message");
});
alert.Show();
}
public void StopCallDiverting()
{
//Stop the call diverting action
}
}
How should i fix this so i can successfully test the dependencyService?
If you have a single activity application you could probably just get away with passing in
Android.App.Application.Context
Eg
AlertDialog.Builder dialog = new AlertDialog.Builder(Android.App.Application.Context);
However to get the current Activity Context in a Multiple Activity Application, then you will need to keep track of it
See this answer for how to keep track of the current context
https://stackoverflow.com/a/47363378/1612975
There is a trick in xamarin to do so.
and most people also consider it very handy approach that is
create a static property of your MainActivity Class inside it (Singleton approach)
internal static MainActivity Instance { get; private set; }
Assign this Instance object value at the end of the construct of MainActivity like this
Instance = this;
Now use it like this to get context where ever you need
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.Instance);
This works well because most of the xamarin forms app have only one activity i.e. MainActivity
this does not work, because your class does not inherit from the Activity/Context class. Therefore this cannot be converted to Android.Content.Context
Just use Android.App.Application.Context to get the current Android Context.
I just had this error and fixed it.
This question is pretty old now but I put my insight for any person meeting the issue.
It turns out it did not like me to put my classes to work with SQLite into the AppName.Android.Persistance namespace instead of AppName.Droid.Persistance.
I just put Droid back and the error has gone.
I am doing an out-of-process semantic logging with elastic search. When i browsed the events using kibana, i could see the events are coming. But the event name showing as "Event name + OpCode". That is events OpCode is being attached to the Event name.
One of my sample event is
Event(RequestStartId, Level = EventLevel.Verbose, Keywords = Keywords.Requests, Task = Tasks.Request, Opcode = EventOpcode.Start)]
public void RequestStart(string message)
{
WriteEvent(message);
}
In elastic search(Kibana) the event name is showing as "RequestStartStart"
Is it normal behavior that the opcode is begin attached to event name ?
That is the built-in behavior of SLAB. You can see it defined in the EventSchema class where the EventName is the TaskName concatenated with the OpcodeName:
public string EventName
{
get { return this.TaskName + this.OpcodeName; }
}
I am currently facing an issue related to logging messages in my WPF application.
I am keeping a static class for logging messages throughout my application which contains a function
private SomeService service = new SomeService();
private void LogMessage(string message)
{
service.Log(message);
}
My issue is in my screens where I require logging, I append strings from different places in the screen and pass it to the LogMessage function. I have very large data to be logged from different places within the screen.
Now the issue I am facing is that a new member has been introduced ie
public bool IsLoggingEnabled = false;
Now I need to check this condition each time before appending the string like this
if(ClassName.IsLoggingEnabled)
{
var msg = string.Format("Log 1 : {0}, Log 2 : {1}, Log 3 : {2} .... ", 0,1,2);
}
if(ClassName.IsLoggingEnabled)
{
msg += string.Format("Log 4 : {0}, Log 5 : {1}, Log 6 : {2} .... ", 4,5,6);
}
...............
ClassName.LogMessage(msg);
Could you please suggest a solution for handling this scenario?
Is it good to append all the messages and finally check the condition. Or check the condition within the LogMessage function?
But I felt these as wrong ways. Any suggestions would be appreciated.
You can instead check this parameter in your login class and keep it transparent to the other places you use it:
private void LogMessage(string message)
{
if(ClassName.IsLoggingEnabled)
{
service.Log(message);
}
}
About the string concatenation why not to just write it in separate logs - each log in it's own call. Makes code clearer and with less state.
Last, I think a better implementation is to have your class dependent on an ILogger instance and to just use it. Somewhere it'll be initialized and passed to your class. This will make it easier for you for change the logging class and to test your other classes.
With your current implementation, the IsLoggingEnabled property can be moved to the static LogMessage and the property can be set once when the project is loaded or through code or from external config file.
Currently I have a custom built static logging class in C# that can be called with the following code:
EventLogger.Log(EventLogger.EventType.Application, string.Format("AddData request from {0}", ipAddress));
When this is called it simply writes to a defined log file specified in a configuration file.
However, being that I have to log many, many events, my code is starting to become hard to read because all of the logging messages.
Is there an established way to more or less separate logging code from objects and methods in a C# class so code doesn't become unruly?
Thank you all in advance for your help as this is something I have been struggling with lately.
I like the AOP Features, that PostSharp offers. In my opinion Loggin is an aspect of any kind of software. Logging isn't the main value an application should provide.
So in my case, PostSharp always was fine. Spring.NET has also an AOP module which could be used to achieve this.
The most commonly used technique I have seen employs AOP in one form or another.
PostSharp is one product that does IL weaving as a form of AOP, though not the only way to do AOP in .NET.
A solution to this is to use Aspect-oriented programming in which you can separate these concerns. This is a pretty complex/invasive change though, so I'm not sure if it's feasible in your situation.
I used to have a custom built logger but recently changed to TracerX. This provides a simple way to instrument the code with different levels of severity. Loggers can be created with names closely related to the class etc that you are working with
It has a separate Viewer with a lot of filtering capabilities including logger, severity and so on.
http://tracerx.codeplex.com/
There is an article on it here: http://www.codeproject.com/KB/dotnet/TracerX.aspx
If your primary goal is to log function entry/exit points and occasional information in between, I've had good results with an Disposable logging object where the constructor traces the function entry, and Dispose() traces the exit. This allows calling code to simply wrap each method's code inside a single using statement. Methods are also provided for arbitrary logs in between. Here is a complete C# ETW event tracing class along with a function entry/exit wrapper:
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace MyExample
{
// This class traces function entry/exit
// Constructor is used to automatically log function entry.
// Dispose is used to automatically log function exit.
// use "using(FnTraceWrap x = new FnTraceWrap()){ function code }" pattern for function entry/exit tracing
public class FnTraceWrap : IDisposable
{
string methodName;
string className;
private bool _disposed = false;
public FnTraceWrap()
{
StackFrame frame;
MethodBase method;
frame = new StackFrame(1);
method = frame.GetMethod();
this.methodName = method.Name;
this.className = method.DeclaringType.Name;
MyEventSourceClass.Log.TraceEnter(this.className, this.methodName);
}
public void TraceMessage(string format, params object[] args)
{
string message = String.Format(format, args);
MyEventSourceClass.Log.TraceMessage(message);
}
public void Dispose()
{
if (!this._disposed)
{
this._disposed = true;
MyEventSourceClass.Log.TraceExit(this.className, this.methodName);
}
}
}
[EventSource(Name = "MyEventSource")]
sealed class MyEventSourceClass : EventSource
{
// Global singleton instance
public static MyEventSourceClass Log = new MyEventSourceClass();
private MyEventSourceClass()
{
}
[Event(1, Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
public void TraceMessage(string message)
{
WriteEvent(1, message);
}
[Event(2, Message = "{0}({1}) - {2}: {3}", Opcode = EventOpcode.Info, Level = EventLevel.Informational)]
public void TraceCodeLine([CallerFilePath] string filePath = "",
[CallerLineNumber] int line = 0,
[CallerMemberName] string memberName = "", string message = "")
{
WriteEvent(2, filePath, line, memberName, message);
}
// Function-level entry and exit tracing
[Event(3, Message = "Entering {0}.{1}", Opcode = EventOpcode.Start, Level = EventLevel.Informational)]
public void TraceEnter(string className, string methodName)
{
WriteEvent(3, className, methodName);
}
[Event(4, Message = "Exiting {0}.{1}", Opcode = EventOpcode.Stop, Level = EventLevel.Informational)]
public void TraceExit(string className, string methodName)
{
WriteEvent(4, className, methodName);
}
}
}
Code that uses it will look something like this:
public void DoWork(string foo)
{
using (FnTraceWrap fnTrace = new FnTraceWrap())
{
fnTrace.TraceMessage("Doing work on {0}.", foo);
/*
code ...
*/
}
}
To make the code readable, only log what you really need to (info/warning/error). Log debug messages during development, but remove most when you are finished. For trace logging, use
AOP to log simple things like method entry/exit (if you feel you need that kind of granularity).
Example:
public int SomeMethod(int arg)
{
Log.Trace("SomeClass.SomeMethod({0}), entering",arg); // A
if (arg < 0)
{
arg = -arg;
Log.Warn("Negative arg {0} was corrected", arg); // B
}
Log.Trace("SomeClass.SomeMethod({0}), returning.",arg); // C
return 2*arg;
}
In this example, the only necessary log statement is B. The log statements A and C are boilerplate, logging that you can leave to PostSharp to insert for you instead.
Also: in your example you can see that there is some form of "Action X invoked by Y", which suggests that a lot of your code could in fact be moved up to a higher level (e.g. Command/Filter).
Your proliferation of logging statements could be telling you something: that some form of design pattern could be used, which could also centralize a lot of the logging.
void DoSomething(Command command, User user)
{
Log.Info("Command {0} invoked by {1}", command, user);
command.Process(user);
}
I think it is a good option to implement something similar to filters in ASP.NET MVC. This is implement with the help of attributes and reflection. You mark every method you want to log in a certain way and enjoy. I suppose there might be a better way to do it, may be with the help of Observer pattern or something but as long as I thought about it I couldn't think of something better.
Basically such problems are called cross-cutting concerns and can be tackled with the help of AOP.
I also think that some interesting inheritance schema can be applied with log entities at the base but I would go for filters