Exceptionless 3.4 - New User Dashboards, Job Reliability, and Bug Fixes

Exceptionless 3.4(/assets/exceptionless-3-4-header.png)

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.

For more information about this release, take a look below and/or review the full release notes over on GitHub.

UI Updates #

These updates were all pushed with Exceptionless.UI 2.5 a few days prior to this release of the main app. Enjoy!

Search Wildcard #

You can now use * to show all events in the search box. Woohoo!

Most Users Dashboard #

The new most users dashboard allows you a quick view of events sorted by the highest number of affected users. This is great for helping prioritize your work pipeline.

Also, as an aside, we've added the users affected column to the dashboard. We know some of you guys will find that helpful.

New Keyboard Shortcuts #

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 g a 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.

Other Updates #

This is just a quick list of everything else we tweaked, updated, added, or fixed with the v2.4 release.

Performance & Reliability #

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.

Heartbeat API Endpoints #

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.

Active Directory Authentication #

Support has been added for Active Directory Authentication. Thanks @laughinggoose! To enable this feature, head over to the Active Directory Authentication documentation page on GitHub.

Count #

This Count property was added to the event model that tracks deduplicated events and allows for some pretty cool metrics from here on out while avoiding the full cost of storing every event.

MaximumRetentionDays #

MaximumRetentionDays is pretty self explanatory. It controls the max retention perdiod for events, which allows the retention job and plans to be smarter about cleaning up old data.

Bugs #

SignalR (web sockets) support wasn't always working in some hosting environments such as AWS, so we fixed a few bugs related to that.

Exceptionless.NET 4.0 - .NET Core and ASP.NET Core Support!

That's right folks, with the release of Exceptionless.NET 4.0 you can now build .NET applications with Exceptionless on Linux, MacOS, and Windows!

We've added .NET Core, ASP.NET Core, and .NET Standard 1.2+ support.

We know many of you have been waiting for this, and it's been a long time coming, but we sat down, put in the hours, and made it happen for you guys!

Exceptionless on Mac OSX(/assets/Screen-Shot-2016-06-28-at-3.08.17-PM.png)

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).

Upgrading #

Updating the NuGet packages should be all you need to do if you are upgrading from Exceptionless.NET v2 or v3. Take a look at the upgrade guide if you have any questions.

Session Heartbeats No Longer Count Towards Plan Limits

session-tracking-revisedThat'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.

Genesis: Exceptionless Session Tracking #

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.

Noise #

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.

Back to the Drawing Board #

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.

Efficiency Achieved! #

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.

Don't Forget to Update Your Client #

If you haven't already updated your client, please do so to start taking advantage of the free session events.

And, as always, please let us know if you've got any feedback or questions. We'd love to hear from you!

New Client Releases Focus on Sessions, Real Time Configuration, and Logging

net-3.5.0-js-1.4.0Exceptionless.NET v3.5.0 and Exceptionless.JavaScript v1.4.0 have been released and they are chock full of new features and feature improvements!

There weren't a whole lot of bug fixes with these releases. Could it be that Exceptionless is working and we've squelched most of the bugs? We think so!

Notably, we focused on sessions, real time configuration, and logging, all of which we think you'll find super helpful.

Read on for details.

Exceptionless .NET Client V3.5.0 and JavaScript Client V1.4.0 Release Notes #

Session Heartbeats No Longer Count Towards Plan Limits! #

We've updated Session Heartbeats and Session End events to be sent through an optimized API end point, and they will no longer count towards your plane's event limits.

Real Time Project Configuration Improvements #

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.



Value: false

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

Key: @@error:*MyCustomException

**Value: **false

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

Key: @@log:*

Value: off

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

**Key: **@@log:MyNamespace.EventPostsJob

**Value: **Info

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:


client.Configuration.UpdateSettingsWhenIdleInterval = TimeSpan.Zero;


client.config.updateSettingsWhenIdleInterval = -1;


New Easy Way to Exclude Events from Being Submitted in .NET #

You can now define a simple Func<Event,bool> callback to stop events from being submitted in the .NET client.

For example, if I wanted to ignore any event with a value property of 2 I could use client.Configuration.AddEventExclusion(e => e.Value.GetValueOrDefault() != 2);

Bug Fix for SettingsCollection Boolean Values Support in .NET Client #

SettingsCollection.GetBoolean(name) was not supporting `` or 1 as boolean values, but now it does. We are also now supporting yes and no as valid values.

JavaScript Client Passing Settings Bug #

@csantero fixed an issue with passing settings to a new isntance of ExceptionlessClient - thanks!

Improved Stacking of Angular Response Errors in JavaScript Client #

^^^ Nothing much to say here - the header says it all!

Feedback #

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!

Thanks for reading and have an awesome day!

Exceptionless Keyboard Shortcuts

keyboard-shortcutsToday 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.

Bringing Up the Shortcut List #

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!

What Shortcuts Exist? #

Event Occurrences #

If you hit SHIFT + / (?) on an event occurrence, you will see three or four new options, depending on whether you are on the first occurrence in the stack or not.

  • **Go to Stack
    ** On any event occurrence, you can hit CTRL + UP to go to that event's stack quicker than finding the "Go To Stack" button and clicking.

  • **Copy Event JSON to Clipboard
    ** Hit CTRL + SHIFT + C to copy that event's JSON data to your clipboard.

  • **Previous Occurrence
    ** CTRL + BACK (LEFT) will take you to the previous event occurrence.

  • **Next Occurrence
    ** And CTRL + FORWARD (RIGHT) will take you to the next occurrence of that event.

Dashboards & Stacks #

On any dashboard or stack, SHIFT + / (?) brings up a simple overlay letting you know that ? will close the overlay and F1 will take you to the Exceptionless documentation on GitHub.

We're open to suggestions for other dashboard or stack shortcuts, just let us know in the comments!

What Shortcuts Would You Use? #

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!

Happy coding.

Know How Many Users are Affected by Bugs and Events

exceptionless user trackingPrioritizing 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!

Who and How Bad Is It? #

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.

Percentage of Users Column #

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.

users affected by bug

Most Users Dashboard #

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.

user event dashboard

Setting User Identity #

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:

using Exceptionless;
ExceptionlessClient.Default.Configuration.SetUserIdentity("UNIQUE_ID_OR_EMAIL_ADDRESS", "Display Name");
exceptionless.ExceptionlessClient.default.config.setUserIdentity('UNIQUE_ID_OR_EMAIL_ADDRESS', 'Display Name');

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.

ASP.NET Example #

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.
using Exceptionless;
ExceptionlessClient.Default.CreateFeatureUsage("MyFeature").SetUserIdentity("123456789", "Blake Niemyjski").Submit();

JavaScript Example #

If you're using the JavaScript client, the entire session of the client will typically be for a single user, so you should be able to set it one time when they log in to your app.

exceptionless.ExceptionlessClient.default.setUserIdentity("id", "friendly name")`

Like with .NET, if you are running a multi-user process (Node.js), you'll need to set the user at the event level.

// javascript
var client = exceptionless.ExceptionlessClient.default;

// Node.Js
// var client = require('exceptionless').ExceptionlessClient.default;

client.createFeatureUsage('MyFeature’).setUserIdentity('123456789', 'Blake Niemyjski').submit();

How Will You Use this Data #

We are always interested in how our users use our features, and if our users feature helps our users help their users, well, that's a win win for our users and their users. Go users!

Don't forget to stop by and let us know if you love or hate it, and of course let us know if you think we can improve on anything within Exceptionless.

Foundatio Featured on .NET Blog + Version 4.0 Release!

Foundatio 4.0 releaseWe've continued to focus some of our attention on our pluggable app foundation block solution, Foundatio, and last week it got some attention from the Microsoft .NET Blog as well!

Foundatio featured as Project of the Week on .NET Blog

We've also released V4.0, which has some new implementations, API changes, and, of course, bug fixes.

Check out the details, below.

Foundatio 4.0 Release Notes #

Implementations #

We've got a few new implementations with this release, including Amazon S3 storage, Azure Service Bus queue (thanks @jamie94bc!), and Redis metrics client. Users should find those helpful.


The APIs have been drastically simplified for ease of use and straightforwardness, which should allow for easier creation of new implementations and consumption of existing ones.

Once example of this simplification is that we've paired down jobs to having only one lock, instead of four.

Logging has also seen huge improvements to make sure we are aligned with future API implementations, etc.

Bugs #

More tests have been added since the previous release, and we've fixed a few major bugs as well.

  • Deadlocks were occurring in a few areas, which is now remedied.
  • Dropped connections are now automatically healed, while previously we were seeing some issues.
  • Cached reference types can no longer be updated.

Upgrading to Foundatio 4.0 #

If you're already using Foundatio, simply updated your NuGet package. If you're new and want to check it out, snag Foundatio over on GitHub.

And, as always, we're here to answer any questions or take any feedback you might have to offer!

Exceptionless V3.3.0 Release - Now with Even More Awesome

Exceptionless 3.3.0 Release Notes

We always work hard to keep improving Exceptionless, and this release is no different!

Since the last release, we've put a lot of time into making the filtering and searching more user friendly and intuitive, improving the reliability of jobs, and of course fixing any bugs that you guys (or Exceptionless) have been able to find.

Let's see what we've got going on, shall we?

What's Goin On? #

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.

New Stats API #

You can now get a timeline or numbers for a comma delimited list of fields using the new stats API, which is pretty cool.

Session Management #

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.

Manual Stacking #

We introduced custom event stacking a few weeks ago, and @adamzolotarev has added the ability to specify a manual stacking key on the client side with this release. Thanks Adam!

Discard events created from bots #

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.

Bugfixes! #

  • Marking stacks as fixed or hidden was causing some significant slow down and sometimes wouldn't work at all. This has been remedied!
  • Redis connection failures and lock timeouts were sometimes causing jobs to stop working or fail. We dug through and found what was causing that and fixed it as well.
  • When the geo field contained a localized number, sometimes events were not being processed. This localization issue has been solved.
  • And last but not least (well, maybe least), a seralization bug has been fixed that would cause query strings, cookies, and other extended data items to be transformed to lowercase and underscored.

Time to Upgrade #

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.

In Conclusion #

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!).

Filter Improvements to the Exceptionless Single Page App

SPA filter search solutionsIt'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.

Filter Changes to the Desktop View #

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.

Before #



After #



Mobile Changes & Functionality #

We also changed the user interface for smaller screens.

Instead of the icons at the top of the screen, the time frame selector is now a major menu item in the mobile menu and displays the current selection with the filter/search field directly below it.

This setup should allow users to filter and find the events they seek much quicker on mobile.

Before #


After #


Pretty Cool, Yeah? #

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!

Simple App Deployment with Azure Continuous Deployment and GitHub

simple app deploymentWe’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.

Exceptionless Deployment History #

In the Beginning #

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.

The Move to Azure #

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.

We knew there had to be a better way.

Two Steps Forward... #

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.

Aha! Eureka! Solution Time! #

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:
  1. 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.
  2. 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.
  3. 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.
  4. Those changes are then automatically pushed via Azure Git Deploy.
  5. Profit!

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!

Detailed Continuous Deployment Setup #

Here are the details on our solution for simple app deployment using GitHub and Azure.

1. Use AppVeyor to build the app. #

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.

github build history artifacts

We can then click on the build to see what artifacts changed.

gitHub build history details

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.

merge-branch-master promote build 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. #

For our .NET application, Exceptionless, we invoke a PowerShell script on post build to clone and commit the changes to the Git artifacts repository.

  1. Our first step is to clone the existing build artifacts repo to an artifacts directory.
  2. Next, we change to the same branch that we are currently building, if it doesn’t exist we create it.
  3. Then, we remove all existing files in the artifacts folder. This ensures we don’t have any conflicts and we can see exactly what was added or removed.
  4. Next, we copy our build artifacts into the artifacts folder. This allows us fine grained control over our artifacts.
  5. Next, we try to commit all artifacts to the artifacts repository. If there were no changes between the last build, then we exit.
  6. Next, we push the artifacts to our GitHub artifacts repository, which will then trigger Azure Continuous Deployment to pick up the changes.
  7. Finally, we create tag the artifacts repository which points to the specific GitHub commit we are building in our main repository.

For our static Angular JavaScript app (UI), we invoke a Grunt publish task from our post build event. The publish task called into a gh-pages task that publishes our built dist folder to the GitHub artifacts repository automatically.

4. Point Azure Continuous Deployment to the Artifacts Repository #

It will see when new artifact commits happen and automatically deploy the changes.

azure sees new artifact commit and deploys

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.

azure override config settings environment variables

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:

  1. environment variables
  2. local config.json file
  3. app settings

It will then fall back to a default value if no explicit settings are found.

Configuring our static Angular JavaScript app is a bit more work since it can't look these settings up dynamically at runtime. So instead we add some code to our deployment process.

  • 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.

Conclusion #

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!