Last active
December 10, 2015 00:29
-
-
Save chgeuer/4351796 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Elmah; | |
| using Microsoft.WindowsAzure.ServiceRuntime; | |
| using Microsoft.WindowsAzure.Storage; | |
| using Microsoft.WindowsAzure.Storage.Table; | |
| using Microsoft.WindowsAzure.Storage.Table.DataServices; | |
| using System; | |
| using System.Collections; | |
| using System.Data.Services.Client; | |
| using System.Linq; | |
| using System.Threading.Tasks; | |
| namespace MvcWebRole1 | |
| { | |
| public class ErrorEntity : TableServiceEntity | |
| { | |
| public string MachineInstance { get; set; } | |
| public string DeploymentId { get; set; } | |
| public string ApplicationName { get; set; } | |
| public string Detail { get; set; } | |
| public string HostName { get; set; } | |
| public string Message { get; set; } | |
| public string Source { get; set; } | |
| public string StatusCode { get; set; } | |
| public string Type { get; set; } | |
| public string User { get; set; } | |
| public string WebHostHtmlMessage { get; set; } | |
| public string SerializedError { get; set; } | |
| public ErrorEntity() { } | |
| public ErrorEntity(Error error) | |
| : base(string.Empty, (DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks).ToString("d19")) | |
| { | |
| var reallyInTheCloud = RoleEnvironment.IsAvailable && !RoleEnvironment.IsEmulated; | |
| this.MachineInstance = reallyInTheCloud ? | |
| RoleEnvironment.CurrentRoleInstance.Id : | |
| Environment.MachineName; | |
| this.DeploymentId = reallyInTheCloud ? | |
| RoleEnvironment.DeploymentId : | |
| string.Empty; | |
| this.ApplicationName = error.ApplicationName; | |
| this.Detail = error.Detail; | |
| this.HostName = error.HostName; | |
| this.Message = error.Message; | |
| this.Source = error.Source; | |
| this.StatusCode = error.StatusCode.ToString(); | |
| this.Type = error.Type; | |
| this.User = error.User; | |
| this.WebHostHtmlMessage = error.WebHostHtmlMessage; | |
| this.SerializedError = ErrorXml.EncodeString(error); | |
| } | |
| } | |
| public class TableErrorLog : ErrorLog | |
| { | |
| public string TableName { get { return "elmaherrors2".ToLower(); } } | |
| private string connectionString; | |
| private CloudTableClient CreateCloudTableClient() | |
| { | |
| return CloudStorageAccount.Parse(connectionString).CreateCloudTableClient(); | |
| } | |
| private TableServiceContext CreateTableServiceContext() | |
| { | |
| return CreateCloudTableClient().GetTableServiceContext(); | |
| } | |
| private DataServiceQuery<ErrorEntity> CreateQuery() | |
| { | |
| return CreateTableServiceContext().CreateQuery<ErrorEntity>(TableName); | |
| } | |
| void Initialize() | |
| { | |
| CreateCloudTableClient().GetTableReference(TableName).CreateIfNotExists(); | |
| } | |
| public override ErrorLogEntry GetError(string id) | |
| { | |
| return new ErrorLogEntry(this, id, ErrorXml.DecodeString(CreateQuery() | |
| .Where(e => e.PartitionKey == string.Empty && e.RowKey == id).Single().SerializedError)); | |
| } | |
| public override int GetErrors(int pageIndex, int pageSize, IList errorEntryList) | |
| { | |
| var context = CreateTableServiceContext(); | |
| var count = 0; | |
| foreach (var error in context.CreateQuery<ErrorEntity>(TableName).Where(e => e.PartitionKey == string.Empty) | |
| .AsTableServiceQuery(context).Take((pageIndex + 1) * pageSize).ToList().Skip(pageIndex * pageSize)) | |
| { | |
| errorEntryList.Add(new ErrorLogEntry(this, error.RowKey, ErrorXml.DecodeString(error.SerializedError))); | |
| count++; | |
| } | |
| return count; | |
| } | |
| public override string Log(Error error) | |
| { | |
| var entity = new ErrorEntity(error); | |
| Task.Factory.StartNew(() => | |
| { | |
| int attempts = 0; | |
| bool success = false; | |
| while (!success && attempts < 5) | |
| { | |
| attempts++; | |
| try | |
| { | |
| var context = CreateTableServiceContext(); | |
| context.AddObject(TableName, entity); | |
| context.SaveChangesWithRetries(); | |
| success = true; | |
| } | |
| catch (Exception) | |
| { | |
| ; | |
| } | |
| } | |
| }); | |
| return entity.RowKey; | |
| } | |
| public TableErrorLog(IDictionary config) | |
| { | |
| var directlyConfigured = (string)config["connectionString"]; | |
| if (!string.IsNullOrEmpty(directlyConfigured)) | |
| { | |
| connectionString = directlyConfigured; | |
| } | |
| else | |
| { | |
| var elmahStorageAccountSettingName = (string)config["elmahStorageAccountSettingName"]; | |
| connectionString = RoleEnvironment.GetConfigurationSettingValue(elmahStorageAccountSettingName); | |
| RoleEnvironment.Changing += (sender, roleEnvironmentChangingEventArgs) => | |
| { | |
| connectionString = RoleEnvironment.GetConfigurationSettingValue(elmahStorageAccountSettingName); | |
| Initialize(); | |
| }; | |
| } | |
| Initialize(); | |
| } | |
| public TableErrorLog(string connectionString) | |
| { | |
| this.connectionString = connectionString; | |
| Initialize(); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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> | |
| <appSettings> | |
| <add key="elmah.mvc.disableHandler" value="false" /> | |
| <add key="elmah.mvc.disableHandleErrorFilter" value="false" /> | |
| <add key="elmah.mvc.requiresAuthentication" value="false" /> | |
| <add key="elmah.mvc.allowedRoles" value="*" /> | |
| <add key="elmah.mvc.route" value="elmah" /> | |
| </appSettings> | |
| <system.webServer> | |
| <modules runAllManagedModulesForAllRequests="true"> | |
| <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> | |
| </system.webServer> | |
| <elmah> | |
| <security allowRemoteAccess="yes" /> | |
| <errorLog type="MvcWebRole1.TableErrorLog, MvcWebRole1" elmahStorageAccountSettingName="elmahStorageAccount" /> | |
| </elmah> | |
| </configuration> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment