The latest Exceptionless release has several additions we think most of our users will find helpful. We sat down and worked on the UI, fixed some bugs, and spend a considerable amount of time improving reliability and efficiency of some of the primary pieces of the app.
If you're a self hoster, you'll need to upgrade your existing install, but if you're hosting with us there is no action required on your part to experiences the Exceptionless 3.4.
MacOS & Linux keyboard shortcut support has been added, as well as additional shortcuts such as C to chat with support, S to focus the search bar, and ga to go to your account. Hit SHIFT + / (also known as ? ) to access the keyboard shortcut list on any screen.
As an aside here, there is also now a </> button near the top of the event occurrence that lets you quickly copy the JSON to your clipboard with a click.
We made several reliability and performance enhancements to queue and job processing. A few specific examples include fixing auto-abandoned jobs and instances where batch events weren't being requeued.
Previously we had worked on making heartbeat events efficient so we didn't have to count them toward event quotas, and with this release we've added new API Endpoints that allow clients to submit those heartbeats cheaply.
The NuGet package now supports .NET Standard 1.2+, PCL Profile 151, and .NET 4.5.
To make upgrading easy, the Exceptionless.Portable NuGet package still exists and is dependent on the Exceptionless Package.
If .NET 4.0 is a requirement for your projects, you will need to continue using the Exceptionless.NET v3.5 NuGet Packages, which are not being deprecated.
As a matter of housekeeping, we removed the ExceptionlessClient.Current property, which was replaced with ExceptionlessClient.Default in v2.0.0, and the configuration EnableSSL properties (also deprecated in v2).
That's right! We've re-imagined how session heartbeats and session end events should work on the back end and were able to make them much more efficient, allowing us to stop counting them toward user plan limits!
This blog post explains our original goals and implementation of these session events, and how we were able to retain the same functionality of the feature while limiting resource usage.
Our hope is that this will obviously make our users happy, but also that all the developers out there can benefit from our process and solution.
In the beginning, we set out to create a sessions feature that allowed our users to submit a session start event and the session would be automatically updated by sending a session heartbeat event, as well as a session end event, respectively.
These session heartbeats and session end events were meant to be session markers to show that a user was active or a session had ended.
We wanted to leverage our existing infrastructure, and the easiest way to do so was to introduce new event types that we recognized. This meant that these events went through the client side plugins (extra work) and server side processing. As such, there was no way to tell these events apart from any other event.
And because of that, they counted against user plan limits.
After releasing the sessions feature, it didn't take us long to notice that the heartbeats were noise. However, we knew that users wanted to see what their customers or users were doing while being active throughout the session, so we didn't remove them.
We knew they were counting towards plan limits, causing some users to reach theirs quickly, and we knew they were adding noise, thus limiting the feature's value, but we also wanted to keep the feature alive because of the potential value offered. So, we had to react and make the entire feature more feasible, streamlined, and cheap.
We did some thinking (and coding), trying to determine the best way we could provide end users with a great session tracking feature without over-taxing our system in the process, and we were able to come up with a solution!
So, we created a new GET API endpoint /api/v2/events/session/heartbeat (api source) that takes a session id or user id and a flag if the session is closed. This API endpoint then sets a unique session cache key with the current time.
Our existing CloseInactiveSessionsJob.cs was already periodically polling for open sessions to check for inactive sessions so it could automatically close them after a period of time if no session end event was sent, so we just updated this job to check for the unique session cache keys (source) and get the last time a heartbeat was sent in or see if it was closed. It then takes the appropriate action and updates the session event.
Then we just updated the clients to call this new API endpoint when client.Submit.SessionHeartbeat("id") or client.SubmitSessionEnd("id") is called.
Our new solution gives us the ability to have clients send us session heartbeat and session end information very efficiently, which lets us provide a great session tracking feature without adding any additional cost to our plans!
That's how we like to roll, and we hope you find value from the feature and our run down of the process we went through to get it to our users.
You can now exclude events by type and source, along with setting minimum log levels, in real time. So, for example, if you accidentally disable logging completely, you can simply update your settings and the updates will go into affect, restoring functionality!
UI support will be expanded moving forward, but for the time being here is an example project configuration.
Any event type or source can be used, and wildcards * are supported, so you can ignore whole event types and set the source to *.
Disable Submissions of Events with Type Name
This configuration will disable submission of any error event with a stack trace containing an exception with a type name that ends with MyCustomException. You could also remove the wildcard and specify the full type name with the namespace.
Log Message Settings
Even though log types are special cased, they still accept rue or false values, so this example completely turns off log messages.
Other known values are Trace, Debug, Info, Warn, Error, Fatal, and Off.
Minimum Log Level
This example is setting the minimum log level for EventPostsJob to Info.
Automatically Check for Updated Configuration Settings on Client Idle #
We've implemented an automatic recurring check for updated configuration settings that occurs two minutes after the last event submission.
A few notes:
Each configuration check does not count towards your account's plan limits.
No user information will be sent - only the current configuration version.
Nothing will be retrieved if no settings have been changed.
The automatic recurring configuration settings check can be disable by calling:
We hope these new features and feature improvements help your Exceptionless experience, and we plan to continue to listen to user feedback and improve the system where improvements need to be made. To do that, though, we need to hear what you want out of the app. If you have a favorite feature request, or something that just bothers you, please let us know by dropping us a line on GitHub Issues under the appropriate repository, listed below, or just comment here and we'll figure it out!
Today we've got a quick article on one of the little known features of Exceptionless: keyboard shortcuts.
In an effort to help you navigate Exceptionless event stacks better and troubleshoot faster, we've added keyboard shortcuts that lets you do things like go to the stack from an individual event occurrence, copy the event JSON, navigate to the previous event occurrence, etc.
Let's take a look at all the quick shortcuts you can use to make your Exceptionless usage more efficient.
To bring up the keyboard shortcuts available to each page, simply hold the shift key and hit the forward slash key (SHIFT + /, think ?). This will bring up an overlay showing you which shortcuts are available on that specific page.
Don't see shortcuts available on a page? Don't freak out, there may just not be any. Feel free to suggest something that you think would save yourself and others time, though!
We'd love to get some community input here. What shortcuts do you think would be useful on which Exceptionless pages? Do you have something you do repeatedly on a dashboard or stack page that you think a keyboard shortcut might speed up or make more efficient? Let us know in the comments and we'll do our best to implement your ideas!
Prioritizing your bug fixes and development time in general can be a daunting task.
Sometimes, as developers, we want to work on this shiny widget or this annoying bug, and we don't really have anything in our face telling us to quit focusing on our dreams and work on what matters to the bottom line.
I can hear you over there: "But, my dreams are important!" Well, yes, but you don't get to have fun working on those until you've made your users happy by fixing the bugs that are affecting the majority of them or expanding on that feature that they are all using every single time they use your app.
We've got something that will let you get those pesky tasks off your plate though, so you can move on to the fun stuff!
Our new "users" column and "Most Users" dashboard lets you know exactly what percentage of your users are being affected by events or using features. This allows you to prioritize the most important bugs or features to work on right away and potentially backlog things that only a few users are having issues with or using.
Of course, you'll need to be sending at least a user id (and preferably a display name) for each user. We'll cover how to do that later in the article.
The new Users column on your Exceptionless dashboard displays a percentage value for each event stack that represents the number of users that have been affected by the event or, if it is a feature, that have used the feature.
If you mouse over the percentage, you can see the number of users the percentage represents out of the total.
These numbers are dynamically calculated for your selected timeframe that you are currently viewing.
Because the main dashboard shows you the most frequent events, not necessarily with the highest usage, we thought it would be helpful to have a new dashboard that automatically sorts event stacks by the percentage of users affected, letting you start at the top of an exception list, for example, and work your way down knowing you're always working on a bug, etc, that is affecting the highest percentage of users.
In order to assure you are getting value out of the user feature, you want to make sure you are setting the user. For Exceptionless to track a user for your app, you need to send a user identity with each event. To do so, you need to set the default user identity via the following client methods:
Once the user is set on the config object, it will be applied to all future events.
Please Note: In WinForms and WPF applications, a plugin will automatically set the default user to the **Environment.UserName** if the default user hasn't been already set. Likewise, if you are in a web environment, we will set the default user to the request principal's identity if the default user hasn't already been set.
You can also manually set the user info on the event directly. This is intended for **multi-user processes (web applications). **For most MVC and WebAPI packages, the user will be set automatically based on the logged in principal, so you don't have to do anything.
// Import the exceptionless namespace. usingExceptionless; ExceptionlessClient.Default.CreateFeatureUsage("MyFeature").SetUserIdentity("123456789","Blake Niemyjski").Submit();
For starters, as mentioned above, we relocated the search bar to exist on the top level of the UI, and the date picker filter now shows the current choice on the top level. Both icons were replaced, and we really think it's much more intuitive and efficient. You can read more and see examples over on the dedicated blog post we did last week.
Session management has been drastically improved by doing a few different things. For instance, inactive sessions are now closed faster, but they can be opened again if need be. We hid heartbeat events by default, too, and you can now specify manual sessions for desktop-based apps.
A default list of bot wild card exclusions is now automatically set on new projects, so if you're upgrading, you now have the ability to run a maintenance job via the admin controller to set a default bot list. All events with user agents matching these wild cards will then be discarded on the client side.
Well, only if you're a self hoster. Everyone else will experience all of these awesome improvements and bug fixes the next time they log in. If you are a self hoster, please review the Self Hosting Docs for info regarding upgrading your current Exceptionless install. Naturally, if you have any questions please let us know and we will get you taken care of.
You can find a complete comparison changelog over on GitHub, where you can also submit any issues, etc if you run across anything. Please also let us know what you think of the changes by commenting below, pinging us on social media, or simply sending Blake a glitter bomb(site/link not endorsed in any way, lol - first one I found!).
It's been a while since we introduced filtering and searching when we launched Exceptionless V2.0, so we decided recently that we wanted to take the feedback we've received and do a round of improvements to it.
You may have already noticed the changes, but if not then the next time you log in you will see that the top bar has changed, giving you much quicker access to filtering and more upfront information.
For the primary desktop view, we removed the magnifying glass icon in the top bar and simply filled the rest the bar with the filter (search) input box. This eliminates a click to get to the filtering system, and keeps it front and center at all times.
One important note here is that if you want to show events that have been marked as fixed or hidden, you have to explicitly specify those filters, whereas previously those options were check boxes. So, you can use hidden:false or hidden:true, and fixed:true or fixed:false to view those events. Naturally, the default is false for both, showing events that have not been hidden or fixed. This means that in order to see both hidden and un-hidden events, you would need to use hidden:false OR hidden:true. Likewise, for fixed, you would need to use fixed:true OR fixed:false.
You'll notice that the date/time filter has changed as well. Instead of an icon, we now display the current time frame being viewed, once again saving you a click and keeping things in front of you.
As always, the filter still applies to the chosen time frame only.
We think it's a pretty nice improvement. We got feedback from several users and think making everything visible at the top level of the user interface is an important change that saves time and keeps you informed.
If you've got any additional feedback, please don't hesitate to let us know. We are always looking for ways to improve, and we use Exceptionless every day too, so we are always interested in saving ourselves time and making things easier on our end!
We’ve learned a lot about simple app deployment since we first started Exceptionless. We initially went with what everyone else was doing (Octopus Deploy), but over time we thought we could greatly simplify and automate it, letting us focus on what matters, improving the product!
Through a lot of testing and iterations of our deployment process, we think we finally nailed it.
As such, we’d like to share with the community how we use Microsoft Azure Continuous Deployment and GitHub for **awesomely simple deployments. **And, how you can too. See the details of implementing this deploy workflow later in the article, below.
When we first started Exceptionless, we deployed it as a monolithic application, meaning the server and UI were one piece, or app. We used Octopus Deploy to deploy to a single IIS machine, which involved setting up a website and server for the Octopus Deploy service and configuring build agents, on each server we deployed to, that could deploy build artifacts.
After a year or so of managing Exceptionless on colocation boxes in a Dallas data center, we realized that we didn’t want to manage hardware anymore and we could scale easier on a managed service like Azure. So, we moved to Azure, where we had to set up a VM just to manage deployments with Octopus Deploy. There were also issues that we ran into with deploying to Azure WebSitThis was annoying, since every time we wanted to do a release we had to log in and tell the system to deploy to production.
Soon, we decided to split the UI and Server apps so we could deploy and work on them independently. This also meant they could scale independently and one change to either wouldn’t cause the whole site to go down when deploying. Splitting the two helped a lot, but it added more work as we now had to manage two Octopus Deploy projects. So, we started looking at the Continuous Deployment in Azure.
We researched further and found out that if we used Git Flow as a development workflow, we could ditch Octopus Deploy completely, remove that dependency, and just use Git push to manage our deployments.
With Git Flow, you do all your work in feature branches and the master branch is always stable. This allows us to set up GitHub deployment on the master and deploy to Azure automatically, with no work required! So anytime we push to the GitHub master branch, it automatically deploys to production on Azure. That simple!
Here is the BASIC workflow:
We create a new feature branch, then work on that branch until it is completed and tested. Testing is done on the website that is currently pointed to the feature branch, which is separate from production.
When we commit to any branch, our continuous integration (CI) server picks up the changes via a GitHub webhook, pulls them down, then builds the project.
We then take all of the build artifacts and push them to a second GitHub repository using the same branch that the code was pushed to (for example, the master branch). This allows you to see exactly what artifacts change between releases (stateless too) and different branches.
Those changes are then automatically pushed via Azure Git Deploy.
This is very slick! Since we push artifacts to the same branch they were built onto a build repository. We can then set up different environments that get auto deployed when we push to that branch. For example: When we are working on a feature, we commit to our branch. We can then set up a new website in Azure that pulls from the build server’s Git artifacts branch for that feature. This allows us to test and automate environments!
2. Store build artifacts in a separate GitHub artifacts repository. #
This works really well because you can see the entire history of your build artifacts and browse their contents. Plus, GitHub hosts it for free!
We found that we could that GitHub could understand and parse into different links. We can click on the "Commit:" part of the message to link to the actual commit that is building to see exactly has changed.
We can then click on the build to see what artifacts changed.
Another great thing about using Git to store your artifacts is that you can easily clone the artifacts to your local machine to see the exact files that are being used in a specific environment.
The artifacts repository has branches to match the branches of our code repo so we have separate build artifacts for each branch. This also means that we can just merge the feature into master when we are done and that will cause the production website that is pointed to our master repository to automatically get updated. So, it’s as simple as merge your branch to master to promote a build to production.
One issue with this approach is that the repo can get large because we are storing binary files that change on every build. We are looking into using Git Large File Support to fix this issue.
3. Automate pushing of artifacts to a secondary GitHub repository. #
4. Point Azure Continuous Deployment to the Artifacts Repository #
It will see when new artifact commits happen and automatically deploy the changes.
Azure Continuous Deployment is another Git repository that we can easily view to see the history of deployments to each of our sites. It also allows us to easily roll back to previous versions.
5. Use Environment Variables to Override Config Settings Per Environment #
Azure Websites makes this very easy.
No production settings are stored in source control or artifacts repository.
For our ASP.NET application, our settings class will look up named settings in the following order:
local config.json file
It will then fall back to a default value if no explicit settings are found.
Azure automatically runs a deploy.sh file after getting the artifacts via git deploy. It’s sole job is to run a node script that rewrites our app.config.js settings with settings defined in environment variables.
You can create multiple Azure websites (think environments) that use Continuous Deployment and point them to multiple artifact branches to support different environments!
Pro Tip: We created a http://local-app.exceptionless.io website for our spa website that’s pre-built and points to your localhost Exceptionless server. This allows us to do work on the server part without setting up or configuring a local instance of our spa app. Development made simple!
We won't lie, it took some work to get here, but the good news is you can do this really easily too. Please feel free to steal our deployment scripts and modify them for your projects. And let us know if you have questions along the way!