Logging to elmah.io from C# and console applications
If you need to log to elmah.io and you cannot use one of the integrations we provide, logging through the Elmah.Io.Client NuGet package is dead simple.
To start logging, install the Elmah.Io.Client
package:
Install-Package Elmah.Io.Client
dotnet add package Elmah.Io.Client
<PackageReference Include="Elmah.Io.Client" Version="5.*" />
paket add Elmah.Io.Client
Create a new ElmahioAPI
:
var logger = ElmahioAPI.Create("API_KEY");
Replace API_KEY
with your API key (Where is my API key?).
The elmah.io client supports logging in different log levels much like other logging frameworks for .NET:
var logId = new Guid("LOG_ID");
logger.Messages.Fatal(logId, new ApplicationException("A fatal exception"), "Fatal message");
logger.Messages.Error(logId, new ApplicationException("An exception"), "Error message");
logger.Messages.Warning(logId, "A warning");
logger.Messages.Information(logId, "An info message");
logger.Messages.Debug(logId, "A debug message");
logger.Messages.Verbose(logId, "A verbose message");
Replace LOG_ID
with your log ID from elmah.io (Where is my log ID?).
To have 100% control of how the message is logged to elmah.io, you can use the CreateAndNotify
-method:
logger.Messages.CreateAndNotify(logId, new CreateMessage
{
Title = "Hello World",
Application = "Elmah.Io.Client sample",
Detail = "This is a long description of the error. Maybe even a stack trace",
Severity = Severity.Error.ToString(),
Data = new List<Item>
{
new Item {Key = "Username", Value = "Man in black"}
},
Form = new List<Item>
{
new Item {Key = "Password", Value = "SecretPassword"},
new Item {Key = "pwd", Value = "Other secret value"},
new Item {Key = "visible form item", Value = "With a value"}
}
});
Structured logging
Like the integrations for Serilog, NLog and, Microsoft.Extensions.Logging, the elmah.io client supports structured logging:
logger.Messages.CreateAndNotify(logId, new CreateMessage
{
Title = "Thomas says Hello",
TitleTemplate = "{User} says Hello",
});
Breadcrumbs
You can log one or more breadcrumbs as part of a log message. Breadcrumbs indicate steps happening just before a log message (typically an error). Breadcrumbs are supported through the Breadcrumbs
property on the CreateMessage
class:
logger.Messages.CreateAndNotify(logId, new CreateMessage
{
Title = "Oh no, an error happened",
Severity = "Error",
Breadcrumbs = new List<Breadcrumb>
{
new Breadcrumb
{
DateTime = DateTime.UtcNow.AddSeconds(-10),
Action = "Navigation",
Message = "Navigate from / to /signin",
Severity = "Information"
},
new Breadcrumb
{
DateTime = DateTime.UtcNow.AddSeconds(-3),
Action = "Click",
Message = "#submit",
Severity = "Information"
},
new Breadcrumb
{
DateTime = DateTime.UtcNow.AddSeconds(-2),
Action = "Submit",
Message = "#loginform",
Severity = "Information"
},
new Breadcrumb
{
DateTime = DateTime.UtcNow.AddSeconds(-1),
Action = "Request",
Message = "/save",
Severity = "Information"
}
}
});
Breadcrumbs will be ordered by the DateTime
field on the elmah.io API why the order you add them to the Breadcrumbs
property isn't that important. Be aware that only the 10 most recent breadcrumbs and breadcrumbs with a date less than or equal to the logged message are stored.
In the example above, only Information
breadcrumbs are added. The Severity
property accepts the same severities as on the log message itself.
Events
The elmah.io client supports a range of different events to help carry out common tasks.
OnMessage
To get a callback every time a new message is being logged to elmah.io, you can implement the OnMessage
event. This is a great chance to decorate all log messages with a specific property or similar.
logger.Messages.OnMessage += (sender, eventArgs) =>
{
eventArgs.Message.Version = "1.0.0";
};
Include source code
You can use the OnMessage
event to include source code to log messages. This will require a stack trace in the Detail
property with filenames and line numbers in it.
There are multiple ways of including source code to log messages. In short, you will need to install the Elmah.Io.Client.Extensions.SourceCode
NuGet package and call the WithSourceCodeFromPdb
method in the OnMessage
event handler:
logger.Messages.OnMessage += (sender, eventArgs) =>
{
eventArgs.Message.WithSourceCodeFromPdb();
};
Check out How to include source code in log messages for additional requirements to make source code show up on elmah.io.
Including source code on log messages is available in the
Elmah.Io.Client
v4 package and forward.
OnMessageFail
Logging to elmah.io can fail if the network connection is down, if elmah.io experiences downtime, or something third. To make sure you log an error elsewhere if this happens, you can implement the OnMessageFail
event:
logger.Messages.OnMessageFail += (sender, eventArgs) =>
{
System.Console.Error.WriteLine("Error when logging to elmah.io");
};
OnMessageFilter
The
OnMessageFilter
event requireElmah.Io.Client
version5.2.*
or newer.
One or more filters can be set up to easily ignore messages based on their messages. To set up a filter, implement the OnMessageFilter
event like this:
logger.Messages.OnMessageFilter += (sender, eventArgs) =>
{
eventArgs.Filter =
eventArgs.Message.Title.Contains(
"foo", StringComparison.InvariantCultureIgnoreCase);
};
This example sets the Filter
property to a boolean indicating if the message should be filtered/ignored or not. In case the log message contains the word 'foo', the message will be ignored.
Bulk upload
If logging many messages to elmah.io, bulk upload can be a way to optimize performance. The elmah.io client supports bulk upload using the CreateBulkAndNotify
-method:
logger.Messages.CreateBulkAndNotify(logId, new[]
{
new CreateMessage { Title = "This is a bulk message" },
new CreateMessage { Title = "This is another bulk message" },
}.ToList());
Options
The elmah.io client contains a set of default options that you can override.
Proxy
To log through a HTTP proxy, set the WebProxy
property:
var logger = ElmahioAPI.Create("API_KEY", new ElmahIoOptions
{
WebProxy = new WebProxy("localhost", 8888)
});
A proxy needs to be specified as part of the options sent to the ElmahioAPI.Create
method to make sure that the underlying HttpClient
is properly initialized.
Obfuscate form values
When logging POSTs with form values, you don't want users' passwords and similar logged to elmah.io. The elmah.io client automatically filters form keys named password
and pwd
. Using the FormKeysToObfuscate
you can tell the client to obfuscate additional form entries:
var logger = ElmahioAPI.Create("API_KEY");
logger.Options.FormKeysToObfuscate.Add("secret_key");
Full example
Here's a full example of how to catch all exceptions in a console application and log as many information as possible to elmah.io:
class Program
{
private static IElmahioAPI elmahIo;
static void Main(string[] args)
{
try
{
AppDomain.CurrentDomain.UnhandledException +=
(sender, e) => LogException(e.ExceptionObject as Exception);
// Run some code
}
catch (Exception e)
{
LogException(e);
}
}
private static void LogException(Exception e)
{
if (elmahIo == null) elmahIo = ElmahioAPI.Create("API_KEY");
var baseException = e?.GetBaseException();
elmahIo.Messages.CreateAndNotify(new Guid("LOG_ID"), new CreateMessage
{
Data = e?.ToDataList(),
Detail = e?.ToString(),
Hostname = Environment.MachineName,
Severity = Severity.Error.ToString(),
Source = baseException?.Source,
Title = baseException?.Message ?? "An error happened",
Type = baseException?.GetType().FullName,
User = Environment.UserName,
});
}
}
The code will catch all exceptions both from the catch
block and exceptions reported through the UnhandledException
event. You'd normally create a shared instance of the elmah.io logger, but in this example, the program will exit just after logging the exception why it doesn't matter. The UnhandledException
event is implemented as a last resort to log any errors not triggering the catch
block. This can be exceptions in background threads, async code, and similar.
This article was brought to you by the elmah.io team. elmah.io is the best error management system for .NET web applications. We monitor your website, alert you when errors start happening, and help you fix errors fast.
See how we can help you monitor your website for crashes Monitor your website