Adding an exception logger to a Web API project with Autofac and Serilog

I just spent way too much time figuring out how to add a catch-all logger for exceptions to an ASP.NET Web API project, so I figured I’d write up my experience as a blog post, for anyone else who needs it (and for my own future reference).

The goal, specifically, is to log any unhandled exceptions using Serilog. I don’t want to mess with them in any way, I just want to record them in the log. (For this API, most exceptions are already properly handled, but sometimes something falls through the cracks, so I just want to be able to see when that happens, so I can fix it.)

First, this is an old-fashioned ASP.NET Web API project, not a .NET Core project. I’m using Autofac for dependency injection and Serilog for logging.

And I’m using the Autofac.WebAPI2 package to integrate Autofac into the API. My Autofac configuration looks pretty much just like the example in the “Quick Start” section of the page linked above.

Serilog is linked in like this:

builder.Register((c, p) =>
{
    var fileSpec = AppDomain.CurrentDomain.GetData("DataDirectory").ToString() + "\\log\\log-{Date}.log";
    var outpTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Properties:j} {Message:lj}{NewLine}{Exception}";
    return new LoggerConfiguration()
        .WriteTo.RollingFile(fileSpec, outputTemplate: outpTemplate)
        .ReadFrom.AppSettings()
        .CreateLogger();
}).SingleInstance();

I won’t get into how that works, but you could figure it out from the Serilog docs easily enough.

ASP.NET Web API provides a way to hook into unhandled exceptions using an ExceptionLogger class. This is described a bit here. I found several blog posts describing various permutations on this functionality, but I had to mess around a bit to get it all to work right for me.
I created a class that looks like this:

public class MyExcLogger : ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        var config = GlobalConfiguration.Configuration;
        var logger = (ILogger)config.DependencyResolver.GetService(typeof(ILogger));
        if (logger != null)
            logger.Error("Unhandled exception: {exc}", context.Exception);
    }
}

and I hooked it up to Web API by adding this line to my WebApiConfig Register() method:

config.Services.Add(typeof(IExceptionLogger), new MyExcLogger());

There’s not actually much to it, but I went down the wrong path on this thing several times, trying to get it to work. The (slightly) tricky part was getting the logger instance from the dependency resolver. Constructor injection doesn’t work here, so I had to pull it out of the resolver manually, which I’d never actually tried before.

Stan Lee

I was sad, but not surprised, to hear about Stan Lee’s passing today. He’s been in poor health for a while, and he was 95 years old. The NY Times has posted a surprisingly length obituary. I took a look at my Twitter timeline this afternoon, and it was full of people posting about him, both comics industry folks and, well, everyone else. I could link to a bunch of other stuff about Stan, but I’ll limit myself to one more thing: Paul Chadwick’s Stan the Mensch blog post from 2010. Just a little story about Stan being kind to a fan; look around the web today, and you’ll find a bunch more like it.

Tom Malinowski

I just watched a segment from Amanpour & Co with Tom Malinowski, my newly-elected congressperson. My local House district has been in Republican hands for as long as I’ve lived here, so it’s kind of a big deal that a Democrat got elected. I actually didn’t see much of Malinowski in the news during the campaign, and I have to admit that I didn’t know that much about him. I never really bothered to do much research. I knew the basics: he worked in the State Department under the Obama administration, and had previously worked for Human Rights Watch. I don’t think I’d ever even seen him speak during the campaign. He seems to be a soft-spoken, reasonable, guy. It’ll be interesting to see what happens over the next couple of years, with the House back under Democratic control. I don’t want to go too far down the politics rabbit-hole, so I’ll leave it there.

John Rogers

I was going to write a post today about how I failed, yet again, to get tickets for next year’s San Diego Comic-Con. But then I saw the news about John Rogers passing away. I hadn’t ever met him, but he’s been president of Comic-Con for the whole time I’ve been going to it (and/or trying to go to it). Thinking about it now, he seems to have kept a pretty low profile over the years, considering his position. So there’s not much I can say about him. But the con has brought me so much joy over the years, and I’m sure his work was a big part of that. So, thank you for your work, John, and rest in peace.

Windows grief, part two

TL;DR: I got through all the steps in my previous post, and now have a semi-functional Windows install.

After getting all the data off my desktop PC SSD, I re-mounted it in the PC, using a different SATA cable, and tried some stuff. The drive was still not bootable, and attempts to repair it were still completely unsuccessful. I did manage to boot from a recovery USB drive that I created via the Dell site. None of the repair options that I could run from that worked, but doing a fresh install of Windows 10 does seem to have worked. At least, it’s working so far.

I’m copying some files back to it right now, while also letting it download Windows updates. That’ll keep it busy for an hour or two. Then, I’ll see if I can reboot and install the updates. If that works, then I’ll look into copying more files back and installing some software. Getting it back to where it was will probably take all week, assuming it holds together and doesn’t start blue-screening again.

If it does keep working, then I have to say that I’m not at all sure what was wrong in the first place. It almost has to have been a software problem. It wasn’t the SATA cable, or the port. If it was either of those, I would have had more luck with it prior to the nuke & pave reinstall. There’s probably no point in speculating too much at this point. I’m just going to keep pushing forward with it, and see how far I get.

Windows grief

The SSD that I installed in my desktop PC a couple of months ago has been working fine. Up until yesterday.

I got a random blue screen error yesterday, while working on the PC. I’ll leave out most of the details, but things went downhill from there. I tried a bunch of stuff, including a chkdsk /f (which didn’t help and probably didn’t finish), SpinRite (which crashed), and various Windows 10 recovery options. Nothing worked.

And I’d recently reformatted the old drive that the SSD replaced, since the SSD was working fine. And I had deleted the old backup of that old drive, so I could make room to do a full backup of the SSD. Which I tried, but couldn’t complete. So I don’t really have a good, full, backup.

This morning, I pulled the new SSD from the desktop computer and mounted it externally on my ThinkPad. It’s been working fine there, and I’ve been copying stuff off it with no problems. Of course, the ThinkPad drive is 500GB and is about half full, while the desktop drive is 1TB and there’s about 400 GB of stuff I need to copy off of it. So I’m shuffling around some old drives so I can copy the files off of the SSD. Copying everything might take up most of the day today.

Since it looks like the drive isn’t actually dead, that probably means that either: (1) the drive cable in the PC is bad, or (2) there’s something wrong on the motherboard of the PC. It’s also possible that there’s some other weird problem that I can maybe fix by doing a full reformat of the drive and reinstall of Windows 10. But I don’t think it’s a Windows problem; if it was, SpinRite likely wouldn’t have crashed, since that’s running from a boot CD. If it’s the drive cable, that’s an easy problem to fix. If it’s a hardware problem on the motherboard, then I need to figure out if I want to try to repair an out-of-warranty Dell desktop PC or just punt and buy a new one.

So my next step, after making sure I’ve got a good copy of all the data off the drive, is to mount it back in the desktop PC, with a new drive cable, and see what happens. If it works, I’ll probably try another chkdsk /f and, if that works, then I’ll breather a sigh of relief and get on with my life, I guess.

If it doesn’t work with the new drive cable, then I’m not sure what I’m going to do. I’ll try a few hardware troubleshooting ideas, and maybe I’ll get lucky. If it’s just a bad SATA port on the motherboard, then I can just use a different one. But if I can’t figure it out, I might decide to buy myself an Intel NUC kit, and transfer the drive and (maybe) memory to it. If I do that, I’ll have to buy a Windows 10 license too, I guess, but overall it should still be more affordable than buying a whole new PC.

Blog posts like this one might not communicate a lot of useful information to anyone, by the way, but I find them to be worth writing, since they allow me to organize my thoughts more than I would otherwise do. I was listening to a podcast yesterday that mentioned rubber ducking, and I guess that’s what I’m doing here, basically. So I don’t know if this post will ever help anyone else, but it helped me.

The Great American Read results

The Great American Read PBS series wrapped up a couple of weeks ago, with To Kill A Mockingbird as the number one book on the list. Here’s a link to the results page for the full list. When the series started, with a special back in June, I joined a Goodreads group related to it, and set myself a challenge to read 13 books from the list, before the show ended. I didn’t quite meet that challenge, but I managed to read 12 books from the list.

Here’s a list of the books I read during the challenge:

  1. Alice’s Adventures in Wonderland by Lewis Carroll
  2. The Sirens of Titan by Kurt Vonnegut
  3. The Martian by Andy Weir
  4. The Little Prince by Antoine de Saint-Exupéry
  5. Siddhartha by Hermann Hesse
  6. The Hobbit by J.R.R. Tolkien
  7. Ghost,
  8. Patina,
  9. and Sunny, all by Jason Reynolds
  10. The Brief Wondrous Life of Oscar Wao by Junot Díaz
  11. 1984 by George Orwell
  12. And Then There Were None by Agatha Christie

So that’s not bad, for my summer reading this year. Several of those books are pretty short, but there are a few longer ones in there too. And a few of them were re-reads. (And I’m not sure if the whole Track series by Jason Reynolds counts as “on the list”, or just the first one, Ghost, but I’m counting them all.) I would have hit my 13-book goal if I hadn’t decided to read Lonesome Dove with the Goodreads group. That’s 900 pages long. (I’m about two-thirds of the way through that.) And I’ve been slowly working my way through Catch-22 at the same time. (I’m about a quarter of the way through that one.)

The Goodreads groups is continuing, and will be reading The Lovely Bones this month and To Kill A Mockingbird next month. I’ve purchased copies of both of those, and plan to read them with the group, though I really want to finish either Lonesome Dove or Catch-22 before starting a new book.

And since I’m posting lists, here’s a list of books from the main 100-book list that I’d like to read, but still haven’t read yet:

  1. Great Expectations
  2. Frankenstein
  3. Game of Thrones (series)
  4. The Picture of Dorian Gray
  5. Invisible Man
  6. Gulliver’s Travels
  7. Ready Player One
  8. The Intuitionist

There are others that I’d probably find interesting, but this is the short list I came up with, after watching the series and reviewing the list again.

Lately, I’ve been going back and forth between reading physical books and ebooks, and between buying books and getting them from the library. All other things being equal, I’d almost always prefer to read the Kindle version for most novels, but I balk at paying the prices that they charge for some Kindle books, especially for older book that (in my mind at least) shouldn’t be priced as high as new books. In cases where I can get the ebook from the library, that’s always the best option. I get the benefits of reading on my Kindle, for free. When I can’t, I’ll often buy a used copy from eBay or Amazon for $4.

Instapaper Premium

Speaking of changes in paid internet services, Instapaper’s new owner has started charging for premium subscriptions again. When they were acquired by Pinterest, they discontinued premium subscriptions and made all features available for free. But the new owner needs to make some money off the service, so they’ve re-instituted Instapaper Premium. I went ahead and signed up for it, at $30/year. As with Flickr Pro, I don’t mind paying for a service, if it means I don’t have to put up with ads or spam or having my data sold off, and if it means that the service has a sustainable business model that will keep it from going under.

more Flickr changes

I’ve been a Flickr user for quite some time. They’ve had some ups and downs over the years, but I have a whole lot of photos there, so I’ve stuck with them. I was happy when they were bought by SmugMug earlier this year. Not much has happened with that, but it looks like some stuff will be changing soon.

First, they’re finally ditching their tie to Yahoo’s login system. That’s long overdue. I’d really like to nuke my Yahoo account, but I’ve had to keep it a lot longer than I’ve wanted to, since my Flickr account is tied to it. They’re also making some other changes, which all sound good, but honestly, just getting off Yahoo’s login system is my main concern.

I’m pretty hopeful about Flickr’s future. The SmugMug CEO is saying a lot of the right things:

Unlike most photo sharing services, SmugMug is photographer-focused and has been for more than 16 years. We are privately owned and operated. We never raised venture capital to grow our business and we don’t make money selling our customers or their data to advertisers.

And:

At SmugMug, we also charged a fair price when others were pretending “free” was actually free. We work for you, not investors or advertisers. We don’t mine you or your photos for data to re-sell or advertise to you. Your data, and your photos, are yours. You’ve entrusted them to us to keep safe. We take that responsibility very seriously and so does Flickr.

That’s what I’m looking for. I don’t mind paying for Flickr Pro. I just want someplace safe and stable to put my photos.

Batman: TAS on Blu-Ray

I’m tempted to pick up the new Batman: TAS Blu-Ray set, but it’s a bit expensive, and I probably won’t get around to watching it anyway. I have the first season on DVD, which I bought many years ago, and probably haven’t watched that yet. (Of course, I’m pretty sure I’ve seen every episode of the series, more than once, back when it was on TV.)