Figured it out. This is similar to the older ExceptionFilter mechanism, but more global as ExceptionFilters only work with unhandled exceptions from a specific controller and not errors that may crop up higher in the stack. First, I needed a simple ExceptionLogger to pass exceptions to Elmah:
public class ElmahExceptionLogger : ExceptionLogger
{
public override void Log(ExceptionLoggerContext context)
{
Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(context.Exception));
}
}
Then added that in WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
}
This does require the latest and greatest MVC/WebAPI (5.1.1 currently).