Skip to content

Instantly share code, notes, and snippets.

@jabez007
Last active March 9, 2018 18:32
Show Gist options
  • Save jabez007/daf10dce2ab0a6f00d0ffed66b19530c to your computer and use it in GitHub Desktop.
Save jabez007/daf10dce2ab0a6f00d0ffed66b19530c to your computer and use it in GitHub Desktop.
Using ELMAH for error logging on a NuGet.Server
using Elmah;
using System.Web;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
namespace LocalNuGet.Elmah
{
class ElmahErrorLogger : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
if (!response.IsSuccessStatusCode)
{
HttpContext context = HttpContext.Current;
ErrorLog.GetDefault(context).Log(new Error(new HttpException((int)response.StatusCode, response.ReasonPhrase), context));
}
return response;
});
}
}
}
using LocalNuGet.Elmah;
using NuGet.Server;
using NuGet.Server.Infrastructure;
using NuGet.Server.V2;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.ExceptionHandling;
using System.Web.Http.Routing;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(LocalNuGet.App_Start.NuGetODataConfig), "Start")]
namespace LocalNuGet.App_Start
{
public static class NuGetODataConfig
{
public static void Start()
{
ServiceResolver.SetServiceResolver(new DefaultServiceResolver());
var config = GlobalConfiguration.Configuration;
NuGetV2WebApiEnabler.UseNuGetV2WebApiFeed(config, "NuGetDefault", "nuget", "PackagesOData");
config.MessageHandlers.Add(new ElmahErrorLogger());
config.Services.Replace(typeof(IExceptionLogger), new TraceExceptionLogger());
// Trace.Listeners.Add(new TextWriterTraceListener(HostingEnvironment.MapPath("~/NuGet.Server.log")));
// Trace.AutoFlush = true;
config.Routes.MapHttpRoute(
name: "NuGetDefault_ClearCache",
routeTemplate: "nuget/clear-cache",
defaults: new { controller = "PackagesOData", action = "ClearCache" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on how to configure your ASP.NET application, please visit https://go.microsoft.com/fwlink/?LinkId=169433 -->
<configuration>
<configSections>
<sectionGroup name="elmah">
<section name="security"
requirePermission="false"
type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog"
requirePermission="false"
type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail"
requirePermission="false"
type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter"
requirePermission="false"
type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>
</configSections>
<!-- For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367. The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.6" />
</system.Web>
-->
<system.web>
<compilation debug="true"
targetFramework="4.6.1" />
<!-- maxRequestLength is specified in Kb -->
<httpRuntime targetFramework="4.6.1"
maxRequestLength="30720" />
<!-- compilation debug="true" targetFramework="4.6" /-->
<httpModules>
<add name="ErrorLog"
type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail"
type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter"
type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
</system.web>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp"
extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4"
compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript"
extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4"
compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
</compilers>
</system.codedom>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0"
path="*."
verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="WebDAV" />
<!-- Depending on IIS configuration, these may have to be added.
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
-->
</handlers>
<staticContent>
<mimeMap fileExtension=".nupkg"
mimeType="application/zip" />
</staticContent>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
<add name="ErrorLog"
type="Elmah.ErrorLogModule, Elmah"
preCondition="managedHandler" />
<add name="ErrorMail"
type="Elmah.ErrorMailModule, Elmah"
preCondition="managedHandler" />
<add name="ErrorFilter"
type="Elmah.ErrorFilterModule, Elmah"
preCondition="managedHandler" />
</modules>
<security>
<requestFiltering>
<!-- maxAllowedContentLength is specified in Bytes -->
<requestLimits maxAllowedContentLength="31457280" />
</requestFiltering>
</security>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<appSettings>
<!-- Determines if an Api Key is required to push\delete packages from the server. -->
<add key="requireApiKey"
value="true" />
<!-- Set the value here to allow people to push/delete packages from the server. NOTE: This is a shared key (password) for all users. -->
<add key="apiKey"
value="" />
<!-- Change the path to the packages folder. Default is ~/Packages. This can be a virtual or physical path. -->
<add key="packagesPath"
value="" />
<!-- Change the name of the internal cache file. Default is machine name (System.Environment.MachineName). This is the name of the cache file in the packages folder. No paths allowed. -->
<add key="cacheFileName"
value="" />
<!-- Set allowOverrideExistingPackageOnPush to false to mimic NuGet.org's behaviour (do not allow overwriting packages with same id + version). -->
<add key="allowOverrideExistingPackageOnPush"
value="false" />
<!-- Set ignoreSymbolsPackages to true to filter out symbols packages. Since NuGet.Server does not come with a symbol server, it makes sense to ignore this type of packages. When enabled, files named `.symbols.nupkg` or packages containing a `/src` folder will be ignored. If you only push .symbols.nupkg packages, set this to false so that packages can be uploaded. -->
<add key="ignoreSymbolsPackages"
value="true" />
<!-- Set enableDelisting to true to enable delist instead of delete as a result of a "nuget delete" command.
- delete: package is deleted from the repository's local filesystem.
- delist:
- "nuget delete": the "hidden" file attribute of the corresponding nupkg on the repository local filesystem is turned on instead of deleting the file.
- "nuget list" skips delisted packages, i.e. those that have the hidden attribute set on their nupkg.
- "nuget install packageid -version version" command will succeed for both listed and delisted packages. e.g. delisted packages can still be downloaded by clients that explicitly specify their version. -->
<add key="enableDelisting"
value="false" />
<!-- Set enableFrameworkFiltering to true to enable filtering packages by their supported frameworks during search. -->
<add key="enableFrameworkFiltering"
value="false" />
<!-- When running NuGet.Server in a NAT network, ASP.NET may embed the server's internal IP address in the V2 feed. Uncomment the following configuration entry to enable NAT support. -->
<!-- <add key="aspnet:UseHostHeaderForRequestUrl" value="true" /> -->
<!-- Set enableFileSystemMonitoring to true (default) to enable file system monitoring (which will update the package cache appropriately on file system changes). Set it to false to disable file system monitoring. NOTE: Disabling file system monitoring may result in increased storage capacity requirements as package cache may only be purged by a background job running on a fixed 1-hour interval. -->
<add key="enableFileSystemMonitoring"
value="true" />
</appSettings>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json"
publicKeyToken="30ad4fe6b2a6aeed"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0"
newVersion="9.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0"
newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0"
newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.7.0.0"
newVersion="5.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.7.0.0"
newVersion="5.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Spatial"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.7.0.0"
newVersion="5.7.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<elmah>
<errorLog type="Elmah.XmlFileErrorLog, Elmah"
logPath="~/ErrorLogs" />
<!-- See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for more information on remote access and securing ELMAH. -->
<security allowRemoteAccess="false" />
</elmah>
<location path="elmah.axd"
inheritInChildApplications="false">
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD"
path="elmah.axd"
type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<!-- See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for more information on using ASP.NET authorization securing ELMAH.
<authorization>
<allow roles="admin" />
<deny users="*" />
</authorization>
-->
</system.web>
<system.webServer>
<handlers>
<add name="ELMAH"
verb="POST,GET,HEAD"
path="elmah.axd"
type="Elmah.ErrorLogPageFactory, Elmah"
preCondition="integratedMode" />
</handlers>
</system.webServer>
</location>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment