JavaScript Client Demo - Exceptionless

Exceptionless JavaScript Client

We're getting closer and closer to version 1.0 of our JavaScript client, and we wanted to give everyone a demo of installation, configuration, and usage.

If you're using Node.js, make sure to check out last week's blog post for Node specific examples. Otherwise, continue reading for JavaScript examples.

As you read and begin playing with the Exceptionless JavaScript client, please make note of any feedback, bugs, etc, and submit a GitHub issue so we can fast track version 1.0 - we surely appreciate it!

How the JavaScript Client was Built #

We built our JavaScript client in typescript 1.5 transpiled it to es5. Our single client works with both Node.js and JavaScript due to dependency injection and a Universal Module Definition (UMD).

Installing the Exceptionless JavaScript Client #

Via Bower #

  1. Install the package by running bower install exceptionless
  2. Add the Exceptionless script to your HTML page. We recommend placing the script at the top of the document to ensure Exceptionless picks up and reports the absolute most potential exceptions and events.
<script src="bower_components/exceptionless/dist/exceptionless.min.js"></script>

Configuring the Client #

Configuration of the Exceptionless JavaScript client can be accomplished a variety of ways. We list the common ways below, but make sure to check the Exceptionless.JavaScript GitHub repo for the most up to date documentation if you run into any problems using this example code.
NOTE: The only required setting you need to configure is the client's apiKey.

Configuration Options #

1. Configure the apiKey as part of the script tag. This method will be applied to all new instances of the ExceptionlessClient

<script src="bower_components/exceptionless/dist/exceptionless.min.js?apiKey=API_KEY_HERE"></script>

2. Set the apiKey on the default ExceptionlessClient instance.

var client = exceptionless.ExceptionlessClient.default;
client.config.apiKey = 'API_KEY_HERE';

3. Create a new instance of the ExceptionlessClient and specify the apiKey or configuration object. Note that the configuration object is optional.

var client = new exceptionless.ExceptionlessClient('API_KEY_HERE'); // Required

// or with a configuration object
//var client = new exceptionless.ExceptionlessClient({
//apiKey: 'API_KEY_HERE',
//submissionBatchSize: 100
//});

Sending Events #

Unhandled exceptions will automatically be sent to your Exceptionless dashboard once the JavaScript client is configured properly. In order to send additional events, including log messages, feature usages, and more, you can use the code samples below and check the Exceptionless.JavaScript GitHub Repo for the latest examples and documentation.

Sending Log Messages, Feature Usages, etc #

var client = exceptionless.ExceptionlessClient.default;

client.submitLog('Logging made easy');

// You can also specify the log source and log level.
// We recommend specifying one of the following log levels: Trace, Debug, Info, Warn, Error
client.submitLog('app.logger', 'This is so easy', 'Info');
client.createLog('app.logger', 'This is so easy', 'Info').addTags('Exceptionless').submit();

// Submit feature usages
client.submitFeatureUsage('MyFeature');
client.createFeatureUsage('MyFeature').addTags('Exceptionless').submit();

// Submit a 404
client.submitNotFound('/somepage');
client.createNotFound('/somepage').addTags('Exceptionless').submit();

// Submit a custom event type
client.submitEvent({ message = 'Low Fuel', type = 'racecar', source = 'Fuel System' });

Manually Sending Errors #

To manually send events other than the automatically reported unhandled exceptions, you can use our fluent event builder API.

The below example demonstrates sending a new error, "test," and setting the ReferenceID, Order and Quote properties, Tags, Geo, UserIdentity, and marking it as Critical.

var client = exceptionless.ExceptionlessClient.default;

try {
throw new Error('test');
} catch (error) {
client.createException(error)
// Set the reference id of the event so we can search for it later (reference:id).
// This will automatically be populated if you call client.config.useReferenceIds();
.setReferenceId('random guid')
// Add the order object (the ability to exclude specific fields will be coming in a future version).
.setProperty("Order", order)
// Set the quote number.
.setProperty("Quote", 123)
// Add an order tag.
.addTags("Order")
// Mark critical.
.markAsCritical()
// Set the coordinates of the end user.
.setGeo(43.595089, -88.444602)
// Set the user id that is in our system and provide a friendly name.
.setUserIdentity(user.Id, user.FullName)
// Submit the event.
.submit();
}

What Data is Collected? #

We built the JavaScript client to be full featured and allow you to report and log all the data our other clients do. It has a fluent API, as mentioned above, and is ready to rock and roll.

We wire up to the window.onerror handler by default, in order to send unhandled exceptions to your Exceptionless dashboard automatically.

Finishing off the Exceptionless JavaScript client features, every event also includes request information.

A few screenshots of an individual event can be found below.

Exceptionless JavaScript Event Request Details

Request Details

Sample

We have put together an example that you can use to get an idea of how everything works. It is available on the GitHub Repo.

To Get the Example Running... #

  1. Clone or download the GitHub Repo
  2. Edit the HTML file in the root example folder and replace the existing API Key with yours. Also, comment out the serverUrl.
  3. Open the HTML file in your browser
  4. Open the console so that you can see the debug messages that the example generates
  5. Click the buttons on the page to submit an event

Troubleshooting

Calling client.config.useDebugLogger(); to enable debug logging is recommend and will output messages to the console regarding what the client is doing. Please contact us by creating an issue on GitHub if you need help or have any feedback regarding the JavaScript client.

Feedback #

As we move forward towards version 1.0 of our JavaScript client, we are looking for any and all feedback, so please don't hesitate to let us know what you think, report a bug, etc.

Happy coding!

Exceptionless Node.js JavaScript Client Demo

Exceptionless Node.js JavaScript Client

Last week we announced our full featured JavaScript client, and we're super excited about releasing a version 1.0 soon.

This week we'd like to put more details out there on the Node.js version of the JavaScript client, including installation, configuration, and usage. We've also set up an Express.js sample app that you can spin up locally to play with things.

Let's take a look.

How the JavaScript Client was Built #

Our javascript client is built in typescript 1.5 and is transpiled to es5. We have a single client that works with both Node.js and JavaScript due to dependency injection and a Universal Module Definition (UMD). For capturing Node stack traces, we use Felixge's Node Stack Trace library.

Installing Exceptionless for Node.js #

  1. Install the package by running npm install exceptionless --save-dev
  2. Add the Exceptionless client to your app:
var client = require('exceptionless.node').ExceptionlessClient.default;

Configuring the Client #

You can configure the Exceptionless client a few different ways for Node.js. The below is the most common way, but for more configuration options and documentation, visit the Exceptionless.JavaScript GitHub repo. NOTE: The only required setting you need to configure is the client's apiKey.

Set the apiKey on the default ExceptionlessClient instance.

var client = require('exceptionless.node').ExceptionlessClient.default;
client.config.apiKey = 'API_KEY_HERE';

Sending Events #

Once configured, the Exceptionless Node.js JavaScript client will automatically send your dashboard any unhandled exceptions that happen in your application. If you would like to send additional event types, such as log messages, feature usages, etc, take a look at the below examples.

Make sure to check out the Exceptionless.JavaScript GitHub Repo for the latest examples and documentation.

Sending Log Messages, Feature Usages, etc #

var client = require('exceptionless.node').ExceptionlessClient.default;

client.submitLog('Logging made easy');

// You can also specify the log source and log level.
// We recommend specifying one of the following log levels: Trace, Debug, Info, Warn, Error
client.submitLog('app.logger', 'This is so easy', 'Info');
client.createLog('app.logger', 'This is so easy', 'Info').addTags('Exceptionless').submit();

// Submit feature usages
client.submitFeatureUsage('MyFeature');
client.createFeatureUsage('MyFeature').addTags('Exceptionless').submit();

// Submit a 404
client.submitNotFound('/somepage');
client.createNotFound('/somepage').addTags('Exceptionless').submit();

// Submit a custom event type
client.submitEvent({ message = 'Low Fuel', type = 'racecar', source = 'Fuel System' });

Manually Sending Errors #

In addition to automatically sending all unhandled exceptions, you can also manually send events to Exceptionless using our fluent event builder API.

The below example demonstrates sending a new error, "test," and setting the ReferenceID, Order and Quote properties, Tags, Geo, UserIdentity, and marking it as Critical.

var client = require('exceptionless.node').ExceptionlessClient.default;

try {
throw new Error('test');
} catch (error) {
client.createException(error)
// Set the reference id of the event so we can search for it later (reference:id).
// This will automatically be populated if you call client.config.useReferenceIds();
.setReferenceId('random guid')
// Add the order object (the ability to exclude specific fields will be coming in a future version).
.setProperty("Order", order)
// Set the quote number.
.setProperty("Quote", 123)
// Add an order tag.
.addTags("Order")
// Mark critical.
.markAsCritical()
// Set the coordinates of the end user.
.setGeo(43.595089, -88.444602)
// Set the user id that is in our system and provide a friendly name.
.setUserIdentity(user.Id, user.FullName)
// Submit the event.
.submit();
}

Express.js Support #

If you are using Express.js to develop a web application, you can add Exceptionless and start collecting unhandled errors and 404s very quickly. To start, just add the following middleware to the bottom of your middleware definitions.

// This middleware processes any unhandled errors that may occur in your middleware.
app.use(function(err, req, res, next) {
client.createUnhandledException(err, 'express').addRequestInfo(req).submit();
res.status(500).send('Something broke!');
});

// This middleware processes 404’s.
app.use(function(req, res, next) {
client.createNotFound(req.originalUrl).addRequestInfo(req).submit();
res.status(404).send('Sorry cant find that!');
});

What Data is Collected? #

The JavaScript/Node.js client is full featured, will collect all the information our other clients collect, and has a fluent API as shown above.

By default, we wire up to the processes' uncaught exception handler to automatically send any unhandled exceptions to your Exceptionless dashboard. We also submit a log message if your app doesn't shut down properly via inspecting the exit code, which is very useful and lets you know what your app is doing. Additionally, any queued up events are processed and sent before your app closes.

Each event contains environment and request information, as well, rounding out the complete list of Exceptionless features that we have made available via the JavaScript client, making it a great error and event reporting/logging solution for all your Node.js projects.

Exceptionless Node.js Event Environment Details

Environment Details

Sample Express.js App

We have built a quick Express.js sample app that you can play around with to get an idea of how the Node.js JavaScript client works with Exceptionless.

Run the sample app by following the steps below:

  1. Install Node.js
  2. Clone or download our repository from GitHub.
  3. Navigate to the example\express folder via the command line (e.g., cd example\express)
  4. Run npm install
  5. Open app.js in your favorite text editor and set the apiKey..
  6. Run node app.js.
  7. Navigate to http://localhost:3000 in your browser to view the express app.
  8. To create an error, navigate to http://localhost:3000/boom

Troubleshooting #

We recommend enabling debug logging by calling client.config.useDebugLogger();. This will output messages to the console regarding what the client is doing. Please contact us by creating an issue on GitHub if you need assistance or have any feedback for the project.

Feedback #

As we move forward towards version 1.0 of our JavaScript client, we are looking for any and all feedback, so please don't hesitate to let us know what you think, report a bug, etc.

Thanks!

JavaScript Client Available for Preview & Testing!

Exceptionless JavaScript Client

That's right ladies and gentlemen, we've been working on a JavaScript client, and it's ready to peak it's head out into the wild.

We're talking beta status here, but version 1.0 is on its way and we wanted to let you guys play with it as soon as possible to provide feedback and help us work out the bugs, etc, quicker.

It's tough to contain our excitement about getting this out there, and we hope you'll check it out!

Exceptionless JavaScript Client Overview #

The client supports Node.js and JavaScript, and you can find up-to-date installation, configuration, and usage documentation over on the GitHub repo.

Just like the non-JavaScript client, unhandled exceptions will be automatically sent upon configuration, and you can send log messages, feature usage events, etc. All the normal Exceptionless functionality is available.

Wanted! #

Testers, developers, contributors, and feedback wanted! We want to make the Exceptionless JavaScript client awesome, but we need your help. Give us any feedback you might have via GitHub an in-app message, contact form submission, or comment right here on this blog post. We're more than happy to answer any and all questions, or help you get up and running.

Exceptionless V2.0.1 Shipped!

This release focused on bug fixes since the 2.0 release and include the below notable changes.

Exceptionless Server #

  • API Status page now also checks the status of Storage, Queues and Message Bus.
  • Added the ability to requeue events (E.X., archived or events that failed to process).
  • Added the ability to send out system and release notifications.
  • Made the event posting and processing async. This has huge performance gains under load.
  • The GeoIP Database is now stored in the storage folder. This made it easier to update it via a job as well as removed some extra configuration settings.
  • Made some minor changes that make it a bit easier to self host (more to come 2.1).

Please take a look at the Exceptionless changelog for a full list of the changes.

Exceptionless.UI #

  • Added a busy indicators to some buttons allowing you to see the state of an action (E.G., Marking a stack as fixed).
  • Added the ability to refresh the app if there is a critical website bug.
  • Fixed a bug where some stack traces couldn't be displayed.
  • Made some minor changes that make it a bit easier to self host (more to come 2.1).

Please take a look at the Exceptionless.UI changelog for a full list of the changes.

Let us know if you have any questions! #

Exceptionless API Usage and Overview

THESE DOCS HAVE BEEN UPDATED. SEE THE NEW DOCS HERE. #

Exceptionless API

So you've been using Exceptionless for a while, but you wish you had a different dashboard, or maybe you'd like to integrate event data into one of your apps. No problem, just use the API!

Through our adventures while building Exceptionless, we've kept open source, automation, and ease of use in mind. With that, we think our API, which utilizes Swagger and Swashbuckle to automatically generate, update, and display documentation (which means it works automatically on self-hosted environments), is a great resource for our users that want to get their hands dirty and use Exceptionless data to roll their own tools, dashboards, etc.

Lets take a closer look at the API, how to use it, and some quick examples of what can be done.

Start Using the Exceptionless API #

Accessing the API #

To access the Exceptionless API, visit https://api.exceptionless.io and click on the "API Documentation" link to be taken to the API documentation.

Get Your User Scoped Token #

Tokens are used to access the api and have roles (scopes). When you authenticate via the login controller action, you are getting a token that impersonates your user so it has the same roles as your user account (e.g., client and user).

Go to Auth controller action and enter your login credentials.

You can enter JSON into the model field, or you an click the yellow box on the right to pre-populate the field with acceptable JSON fields. Just replace the values that you want to specify and remove the fields you don't need, like invite token.

Exceptionless API Get User Scoped Token

Click "Try it out!" and generate your token. Take note of the response messages section above the button, as it details the possible codes that would be returned in the event of an error (e.g. 401 if the user name or email address was incorrect).

Retrieve Exceptionless User Scoped Token

You can see from the response that it returned our token from the request url above. Take your generated token and put it in the "api_key" field at the top of the page and click "Explore." This authorizes you via bearer authentication, authenticates you to the rest api, and allows you to call controller actions.

Add Exceptionless User Scoped Token

Get a New Token #

Now, we’ll get a new token for the project we want to work on and assign it a user role (scope) of "user." We want to get a new user scoped token because we want to do more than just post events (client scoped tokens only allow you to post events), we want to retrieve them. Creating a new token also allows us to revoke the token later.

First, get your project ID from the Exceptionless Dashboard. It can be found in the URL of that project’s dashboard.

Get Exceptionless Project ID

Now, we’ll navigate to Tokens > POST /api/v2/projects/{projectId}/tokens, enter our Project ID, and set up our token to include the user scope and a quick note.

Create Exceptionless Token

Next, we'll click "Try it out!" and generate our new token id.

Get new Exceptionless Token ID

Now, once again, copy this new token and place it in the "api_key" field at the top of the page and click "Explore." Now everything we do will be authenticated to this new user token you’ve just created.

Posting an Event #

Now, lets post an event with a reference ID that we’ll use for a few other examples.

First, navigate to Event > POST /api/v{version}/events

Exceptionless API Post Event

You’ll see a few basic examples of events and some explanation of the resource in this panel. Make sure to give it a read. For this example, we’ll use a simple log event, with a brief message, and add a reference ID to it. Note that you must also enter the current API version in the "version" field.

When we click "Try it out!" and get a 202 response code, we know we’ve created an event.

Exceptionless API Created Event

Get Event by Reference ID #

If we want to get the event we just created by it’s reference_id, we can navigate to Event > GET /api/v2/events/by-ref/{referenceId}, enter that reference ID, and get back the details of the event.

Get Exceptionless Event by ReferenceID

Getting the Event via a Search Filter #

Another example of getting an event may include using the reference ID or another search filter we just created and getting all by a reference filter. You can use any search filter in the filter parameter.

To do so, navigate to Event > GET /api/v2/events and use the reference term to filter events by the reference ID.

Exceptionless API Get All Filter Search

Results

Exceptionless API Get Al Filter Search Results

Get Organizations and Projects #

Naturally, we can get all the organizations or projects associated with the current authorized token, as well.

Organizations

Navigate to Organization > GET /api/v2/organizations and click "Try it out!"

Exceptionless API Get Organization Results

Projects

Navigate to Project > GET /api/v2/projects and click "Try it out!"

Exceptionless API Get Projects Results

How to Authenticate to the API

1. Bearer Authentication #

The api documentation uses bearer authentication to authenticate to the API. You can do this in your apps too by specifying a bearer authorization header with your token as shown below.

Exceptionless Bearer Authentication

2. Authenticate via the Query String #

Everything we’ve shown you today can be easily and cleanly accessed via a URL query string and your access token.

For example, if we want to view our organizations, we simply navigate to https://api.exceptionless.io/api/v2/organizations, add the query string "?access_token={token}" and press enter to get the data.

Exceptionless Query String API Authentication

Let Us Know What You Think! #

We've tried to make the API as easy and intuitive to use as possible, but we're always open to feedback and comments, so please let us know what could be better, easier, faster, etc.

And, of course, if you have any questions about the API, please leave a comment here, send us an in-app support message, or simply submit the website contact form.

Filter and Searching Tutorial Video - Exceptionless

Exceptionless Search FilteringOne of the most requested features from the beginning of Exceptionless 1.0 was a filtering and searching system. When we started developing Exceptionless 2.0, we knew it was one of the major features we wanted to include.

We couldn't just throw in a string search and hope for the best. We had to build it in a way that let users perform basic and advanced filtering, easily, with fast and streamlined results.

Enter Exceptionless filtering and searching. You can filter by organization, project, multiple time frame selectors, and specific event variables (with modifiers).

Watch the video below for a quick test drive, and read further down the page for more details and links!

Exceptionless Filtering and Search Demo Video #

Filter by Organization & Project #

Exceptionless Organizations and Projects

By default, the dashboard loads up with all projects selected.

To show only data from a specific organization or project within an organization, simply click on the "All Projects" drop down in the top left of the dashboard and select your organization or project.

Whatever view you are in will then be transformed to display only data from that organization/project.

To change it back to all projects, simply select the drop down again and click on "All Projects."

Filter by Time Frame #

Exceptionles Time Frame Filters

Exceptionless offers multiple preset time frame options, as well as the ability to customize the time frame down to the second.

To select your time frame of choice, click on the calendar icon next to the project drop down on the top navigation bar of your dashboard.

Once there, you can select "Last Hour," "Last 24 Hours," "Last Week," "Last 30 Days," "All Time," or "Custom."

Most of these options are pretty self explanatory, but if you click on "Custom," a popup will appear that lets you select the start and end date, as well as start and end hours, minutes, and seconds of those dates.

Another way to control the data time frame is to simply select a period of time on the history graph itself by clicking, dragging, and releasing. This will automatically update the custom time frame points and refresh the data to match that period.

Filter and Search by Specific Criteria #

Exceptionless Search Filter Feature

Being able to search your errors and events by specific criteria is, perhaps, the largest improvement for version 2.0.

By selecting the magnifying glass icon next to the calendar icon in the top navigation, you can enter search criteria and select whether you want the results to include fixed and/or hidden events/errors.

You can filter by tag, ID, organization, project, stack, type, value, IP, architecture, user, and much much more. Some searches, such as ID, require a prefix ("id:") on the search, but others, such as error.message, can be entered as strings ("A NullReferenceException occurred"). View a complete list of searchable terms, examples, and FAQs on our Searching Documentation Page.

We're Always Improving - What Could be Better? #

Please let us know what you think of the filtering and searching abilities by commenting here on the blog, sending us an in-app support message, or filling out our contact form. We're always looking for feedback, and genuinely want to know what you think!

An Exceptionless NuGet Package Tour

Exceptionless NuGet PackagesGiving back to the development community is important to us over here at Exceptionless. We love open source!

As such, the Exceptionless NuGet assembly library, with 31 assemblies and over 176,000 package downloads, is ever growing and expanding right along with our GitHub repos.

We thought we would give everyone a quick tour, and at the same time perhaps provide a good resource and reference page.

Don't forget, though - this page may be out-dated by the time you view it, so please view our full library on NuGet.

Exceptionless NuGet Clients #

Exceptionless, our primary open source application, provides real-time error, feature, and log reporting for ASP.NET, Web API, WebForms, WPF, Console, and MVC apps (and more, soon!).

Below you will find the NuGet assemblies for all the platforms we currently support.

Exceptionless.Portable
Exceptionless client for portable (PCL) applications. This is the base library all the other implementations build on top of. It contains all the basic functionality that powers the Exceptionless clients! This library can be used on many different platforms. It’s worth noting that this is a very basic client and as such you won’t get all the bells and whistles as described here in the PCL configuration section. For those bells and whistles, see the Exceptionless package, below.
Frameworks: .NET 4, .NET 4.5, Silverlight 5, Windows 8, Windows Phone 8.1, Windows Phone Silverlight 8

Exceptionless
Exceptionless client for non visual (ie. Console and Services) applications.** **We recommend using this package if you are not using any other platform specific packages (E.G., Exceptionless.Mvc), as it provides all the bells and whistles that are missing in the portable package.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.Mvc
Exceptionless client for ASP.NET MVC 3+ applications.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.WebApi
Exceptionless client for ASP.NET Web API applications.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.Web
Exceptionless client for ASP.NET WebForms applications.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.Nancy
Exceptionless client for Nancy applications.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.Wpf
Exceptionless client for WPF applications.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.Windows
Exceptionless client for Windows Forms applications.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.NLog
NLog target that sends log entries to Exceptionless.
Frameworks: .NET 4.0, .NET 4.5

Exceptionless.Log4net
Log4net appender that sends log entries to Exceptionless.
Frameworks: .NET 4.0, .NET 4.5

Serilog.Sinks.ExceptionLess
Serilog sink that sends log entries to Exceptionless.
Frameworks: .NET 4.0, .NET 4.5
View Source

Signed Assemblies #

We also have signed versions of most assemblies on our NuGet Profile. See MSDN for additional info on signing assemblies (Strong-Named Assemblies).

Foundatio by Exceptionless #

Foundatio (Requires .NET 4.5) is an open source library for building distributed applications that we built, use, and think you will find helpful. Foundatio provides in memory, redis, and azure implementations. This allows you to do development or testing using in-memory versions and switch them out for redis or azure implementations in production. This saves you time (setup and maintaining) and money (not paying for cloud resources) during development and testing! Foundatio source code can be found at https://github.com/FoundatioFx/Foundatio.

Exceptionless was built using Foundatio and utilizes implementations for caching, queues, locks, messaging, jobs, file storage, and metrics.

Foundatio
Foundatio consists of pluggable foundation blocks for building distributed apps, including caching, queues, locks, messaging, jobs, file storage, and metrics.

Foundatio Redis Implementations
Contains the redis implementations of caching, queues, locks, messaging, jobs, file storage.

Foundatio Azure ServiceBus Implementations
Contains the redis implementations of queues and messaging. The azure packages are split into different packages so you don't have to take extra azure dependencies on things you don't need.

Foundatio Azure Storage Implementations
Contains the redis implementations of file storage. The azure packages are split into different packages so you don't have to take extra azure dependencies on things you don't need.

Other #

Exceptionless LuceneQueryParser
Lucene Query Parser is a lucene style query parser that is extensible and allows additional syntax features. We use this in Exceptionless to ensure the query is valid before executing it, check to see if you are trying to a basic or premium search query and much more!
Frameworks: .NET 4.5
View Source

Exceptionless RandomData
RandomData is a utility class for easily generating random data, making the creation of good unit test data a breeze.
Frameworks: .NET 4.0, .NET 4.5
View Source

Exceptionless DateTimeExtensions
This package includes DateTimeRange, Business Day, and various DateTime, DateTimeOffset, and TimeSpan extension methods.
Frameworks: .NET 4.0, .NET 4.5, Windows 8, Windows Phone 8.1
View Source

We'll Keep Building! #

We don't plan on stopping anytime soon, and will continue writing assemblies to make life easier for developers everywhere. Naturally, we could always use your help, so fork us on GitHub if you feel like chipping in. We always appreciate our contributors!

Otherwise, let us know what you think of Exceptionless, Foundatio, and all our other projects. Feedback is always welcomed and appreciated.

How to Add a Plugin to Affect Events in Exceptionless

Exceptionless PluginsA plugin is a client-side addin that is run every time you submit an event.

Plugins can be used to add or remove data from an event, or even allow you to cancel an event submission.

Each client-specific implementation registers a plugin to provide client-specific information like request info, environmental info, etc. These abilities make plugins very powerful.

Let's take a more in-depth look at Exceptionless Plugins and how they are used.

Pre-Reqs #

First, we are assuming that you have already created an account and installed and configured the latest version of the Exceptionless client (plugins require client v3 - released 4/6/2015). If you are still using the 1.x client, you will need to upgrade to use plugins.  Please contact support via an in-app support message or our contact page if you have any questions or need assistance in this area.

Creating a New Plugin #

Before we create our first plugin, it’s important to keep in mind that each plugin will run every time an event is submitted. As such, you should ensure your plugins are fast and not super resource-intensive so your app remains as quick as possible.

To create a plugin, you have to specify a System.Action, or create a class that derives from IEventPlugin.

Every plugin is passed an EventPluginContext, which contains all the valuable contextual information that your plugin may need via the following properties:

  • **Client
    ** The ExceptionlessClient that created the event.
  • **Event
    ** The target event.
  • **ContextData
    ** Allows plugins to access additional contextual data to allow them to add additional data to events.
  • **Log
    ** An ExceptionlessLog implementation that lets you write to the internal logger. This internal logger is used only when debugging the client.
  • ****Resolver
    **** The ExceptionlessClient`s dependency resolver. This is useful for resolving other dependencies at runtime that were not requested via constructor injection.

Exceptionless Plugin Example - Add System Uptime to Feature Usages #

The following system uptime plugin derives from IEventPlugin and places the system uptime into every feature usage event as extended data when the plugin’s Run(context) method is called.

using System;
using System.Diagnostics;
using Exceptionless.Plugins;
using Exceptionless.Models;

namespace Exceptionless.SampleConsole.Plugins {
[Priority(100)]
public class SystemUptimePlugin : IEventPlugin {
public void Run(EventPluginContext context) {
// Only update feature usage events.
if (context.Event.Type != Event.KnownTypes.FeatureUsage)
return;

// Get the system uptime
using (var pc = new PerformanceCounter("System", "System Up Time")) {
pc.NextValue();

var uptime = TimeSpan.FromSeconds(pc.NextValue());

// Store the system uptime as an extended property.
context.Event.SetProperty("System Uptime", String.Format("{0} Days {1} Hours {2} Minutes {3} Seconds", uptime.Days, uptime.Hours, uptime.Minutes, uptime.Seconds));
}
}
}
}

Output in Exceptionless:

Exceptionless Plugin System Uptime

Note: We kept the formatting of the uptime simple for the sake of this example, but we recommend using our open source DateTimeExtensions library if you wish to format it in a really pretty manner.

Plugin Priority

You might have noticed that there is a priority attribute with a value of 100. The priority of a plugin determines the order that the plugin will run in (runs in order of lowest to highest, and then by order added). All plugins that ship as part of the client start with a priority of 10 and increment by multiples of 10. If you want your addin to run first, give it a low priority (e.g., 0, 1, 2, 3, 4, 5). If you want it to run last, give it a high priority (>100). By default, if you don’t specify a priority, 0 will be used.

To make sure your plugin runs first (if required), you can inspect the configuration's plugin property in Visual Studio while debugging.

foreach (var plugin in Exceptionless.ExceptionlessClient.Default.Configuration.Plugins)
Console.WriteLine(plugin);

Exceptionless Plugin Priority

Adding the Plugin to Your App #

Now that we've created the plugin, we’ll add it when our application starts up by calling one of the Exceptionless.ExceptionlessClient.Default.Configuration.AddPlugin() overloads.

In most cases, we use the following overload to register plugins:

using Exceptionless;
ExceptionlessClient.Default.Configuration.AddPlugin<SystemUptimePlugin>();

When you add a plugin by specifying the type, we inspect the type and try to find a PriorityAttribute. If we can’t find one, the default value of 0 will be used.

You can also add a plugin by passing a System.Action to AddPlugin.
Please note that we are specifying a key when adding the action plugin so we can remove it later. If you are not going to be removing your plugin, then you can omit the first argument.

We pass AddPlugin three arguments:

  • A unique plugin key (which can be used to remove the plugin later)
  • Priority
  • An action that contains all of our logic to add the system uptime (or whatever your plugin does).
using Exceptionless;
ExceptionlessClient.Default.Configuration.AddPlugin("system-uptime", 100, context => {
// Only update feature usage events.
if (context.Event.Type != Event.KnownTypes.FeatureUsage)
return;

// Get the system uptime
using (var pc = new PerformanceCounter("System", "System Up Time")) {
pc.NextValue();
var uptime = TimeSpan.FromSeconds(pc.NextValue());

// Store the system uptime as an extended property.
context.Event.SetProperty("<wbr />System Uptime", String.Format("{0} Days {1} Hours {2} Minutes {3} Seconds", uptime.Days, uptime.Hours, uptime.Minutes, uptime.Seconds));

}
});

Removing an Existing Plugin #

To remove a previously added plugin, you need to call one of the Exceptionless.ExceptionlessClient.Default.Configuration.RemovePlugin overloads.

using Exceptionless;
ExceptionlessClient.Default.Configuration.RemovePlugin<SystemUptimePlugin>();

If you registered your plugin via an action, you will need to remove the plugin with the key it was added with.

using Exceptionless;
ExceptionlessClient.Default.Configuration.RemovePlugin("system-uptime");

How Can You Use Plugins? #

Can you think of ways that plugins can help your app? Are you already building some? Let us know what they are and how they help! Eventually, we plan on building a library of useful and common plugins that other developers can easily implement. The more help we've got, the faster that library will grow!

Sending Log Messages to Exceptionless

Exceptionless Log Message EventsWe're all about exceptions, but sometimes, as developers, we run into bugs that don't throw them but still cause major havoc in the system. There are also times we just need to record an event with a custom message to help track down bottlenecks, etc.

That's where Exceptionless meets log messages.

In Exceptionless 2.0, you can now send custom log messages to a Log Messages dashboard where they can be tracked and view just like exceptions and other events.

Lets take a closer look...

How to Submit a Log Message to Exceptionless #

Using the Client #

For this example, we are assuming that you have already created an account and installed and configured the Exceptionless 2.0 client. If you are still using the 1.x client, you will need to upgrade to send us log messages. Please contact support via an in-app support message or our contact page if you have any questions or need assistance in this area.

Let's submit a log message
using Exceptionless;
ExceptionlessClient.Default.SubmitLog("Application starting up");

That's your basic log message.

Getting fancier, you can also specify the log source and log level.

In the below example, "typeof(MainWindow)__.FullName" specifies the log source, and "Info" specifies the log level. If no log source is specified, the log messages will be stacked under a global log stack.

We recommend specifying one of the following log levels, all of which add a visual indicator to each log message (see below screenshot).

  • Trace
  • Debug
  • Info
  • Warn
  • Error
ExceptionlessClient.Default.SubmitLog(typeof(MainWindow).FullName, "Info log example", "Info");

Here's a screenshot of what the visual indicators for the different types of log levels look like.

Exceptionless Log Message Preview

You can also add additional information using our fluent API.

This is helpful wen you want to add contextual information, contact information, or a tag.

In the below example, we will use the "CreateLog" method to add a tag to the log message.

using Exceptionless;
ExceptionlessClient.Default.CreateLog(typeof(MainWindow).FullName, "Info log example", "Info").AddTags("Wpf").Submit();

There are a number of additional pieces of data you can use for your event. The below bullets include the current EventBuilder list, but we are always adding more that can be found on GitHub. Also, view more examples here on our Sending Events page.

  • AddTags
  • SetProperty
  • AddObject
  • MarkAsCritical
  • SetUserIdentity
  • SetUserDescription
  • SetVersion
  • SetSource
  • SetSessionId
  • SetReferenceId
  • SetMessage
  • SetGeo
  • SetValue
  • And more, depending on your client

Using the REST API #

You can also submit a log message with an HTTP post to our events endpoint.

My log message
My second log message.

By default, any content that is submitted to the API post is a log message. The above example will be broken into two log messages because it automatically splits text content by the new line.

You can submit a log message via JSON, too.

See details in our API Documentation. If you need an API key for simply posting events, you can find it in your project settings. Otherwise, please refer to the auth login documentation to get a user scoped api key.

Below is a JSON example of a log message, with source, message, and log level.

{
"type": "log",
"source": "WpfApplication3.MainWindow",
"message": "Application started",
"data": {
"@level": "Info",
}
}

Using NLog or Log4net Targets #

We also have integrations with major logging frameworks. The benefits of using a logging framework is finer, more granular control over what is logged.

For example, you can log only warnings or errors project-wide, but then enable trace level messages for a specific class. We do this to keep our system from getting filled up with noise that doesn't add any value unless there is an issue.

This also allows you to quickly change what you want to log to. Maybe you want to turn off logging to Exceptionless, or log to Exceptionless and to disk.

NLog or Log4net Usage

To use the NLog or Log4net clients, you’ll just need to bring down the NuGet package and follow the detailed readme.

Note on performance: Use in-memory event storage for high volumes

There are some performance considerations you should be aware of when you are logging very high numbers of log events and using our client. We've spent a lot of time to ensure Exceptionless doesn't degrade your applications performance. However, if you are logging thousands of messages a minute, you should use the in-memory event storage.

using Exceptionless;
ExceptionlessClient.Default.Configuration.UseInMemoryStorage();

This tells the client not to serialize the log events to disk before sending and thus is much faster (the client doesn't need to serialize the event to disk and read it from disk before sending). This comes at the expense that if the application dies, you will lose any unsent events that were in memory. When you use the NLog or Log4net targets and specify the API key as part of the target configuration, we will automatically create a second client instance that uses in-memory storage only for log messages. This way, any logged exceptions or feature usages still use disk storage, while log messages use in-memory storage, allowing maximum performance.

Another Note: We are also working on updating the Serilog implementation.

Log Messages Dashboard #

The Log Messages Dashboard makes it easy to see log occurrences. You can keep track of how active a component is, or how long code takes to execute using existing metrics.

For metrics, we have created an open source metrics library called Foundatio. We use it for Exceptionless, and think you will find it extremely helpful as well. Check it out! We'll be posting an article on Foundatio soon, so check back.

log-messages-dashboard #

How Are You Liking Exceptionless 2.0?

We think we've added some pretty cool features to Exceptionless 2.0, including logging, but you are the ultimate judge. What's good? What's bad? What's missing? Let us know via a comment on the blog, social media, in-app, or however else you want to get in touch!

If you're new to Exceptionless 2.0, make sure to check out the launch article for more details on the new features and enhancements.

Logging Feature Usages with Exceptionless

Exceptionless Feature UsageThe ability to log feature usages is one of the many new... features... of Exceptionless 2.0.

If you want to know when a button is being clicked, or what users are doing certain tasks, feature usage logging will help you track and visualize each occurrence.

What you learn from logging these types of feature usages might surprise you, and at the very least you'll know more about how users interact with your system.

How to Submit a Feature Usage #

Using the client #

For this example, we are assuming that you have already created an account and installed and configured the Exceptionless 2.0 client. If you are still using the 1.x client, you will need to upgrade to send us feature usage events. Please contact support via an in-app support message or our contact page if you have any questions or need assistance in this area.

Example 1 - Signup

In the example below, we are going to submit a feature usage when any user signs up.

To submit the feature occurrence, you just need to call our api as follows:

using Exceptionless;
ExceptionlessClient.Default.SubmitFeatureUsage("Signup");

SubmitFeatureUsage creates a simple feature usage and submits it. To include more information, please use CreateFeatureUsage (example below).

More detailed examples

You can also submit additional information with a feature usage using our fluent api. This is nice when you want to add contextual information, contact information, or a tag.

Example 2 - Signup with tags

If, for instance, you wanted to indicate how a user signs up, you can add a tag to the feature usage occurrence. In the below example, we are tagging a feature usage that uses GitHub to sign up.

using Exceptionless;
ExceptionlessClient.Default.CreateFeatureUsage("Signup").AddTags("GitHub").Submit();
Example 3 - Who's Searching?

As another example, maybe we want to log a feature usage when users search, and then set their identity.

using Exceptionless;
ExceptionlessClient.Default.CreateFeatureUsage("Searching").SetUserIdentity("John Smith");
What else can I add to a submission?

There are a number of additional pieces of data you can use for your event. The below bullets include the current EventBuilder list, but we are always adding more that can be found on GitHub. Also, view more examples here on our Sending Events page.

  • AddTags
  • SetProperty
  • AddObject
  • MarkAsCritical
  • SetUserIdentity
  • SetUserDescription
  • SetVersion
  • SetSource
  • SetSessionId
  • SetReferenceId
  • SetMessage
  • SetGeo
  • SetValue
  • And more, depending on your client

Using the REST API #

You can also submit a feature usage by posting JSON to our API. See details in our API Documentation. If you need an API key for simply posting events, you can find it in your project settings. Otherwise, please refer to the auth login documentation to get a user scoped api key.

{
"type": "usage",
"source": "Signup"
}

The Dashboard #

Feature usage logging makes it very easy to see how often a feature, such as logging into an account, is used over time. If usage of one type of login, for instances, is never used, there might be an issue or you could consider removing it (less code debt). Or, if one is used the majority of the time, maybe it should be first in the list. There are almost unlimited ways you can use feature usage data to improve user experience.

Exceptionless Feature Usage Dashboard

If we click on the stack for the signup feature, it shows the tag list of the providers that have been used to signup (GitHub and Google, in this instance).

Exceptionless Feature Usage Stack

You can even go further and filter by a tag to see exactly how people are logging into your system using the search filter. Example: "tag:GitHub"

Exceptionless Feature Usage Filtering Searching

Regarding the SetUserIdentity example above, we can see that user information being appended to a feature usage occurrence if we visit the "Search" feature and view an occurrence.

Exceptionless Feature Usage User Info

Cool Stuff, Right? #

We think so, and we hope you do too. Either way, we're always looking for feedback, so let us know what you think via the comments below, an in app support message, or via the contact page.