Skip to content

Commit 6f49dfe

Browse files
committed
Merge pull request #2 from Iristyle/master
Supplemental bridge code to enable SS errors to bubble up to Elmah properly
2 parents 25f96e8 + 510ac09 commit 6f49dfe

10 files changed

Lines changed: 381 additions & 29 deletions

File tree

build/deploy.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
COPY ..\src\ServiceStack.Logging.EventLog\bin\Release\ServiceStack.Logging.EventLog.* release\ServiceStack.Logging\EventLog
22
COPY ..\src\ServiceStack.Logging.Log4Net\bin\Release\ServiceStack.Logging.Log4Net.* release\ServiceStack.Logging\Log4Net
33
COPY ..\src\ServiceStack.Logging.Log4Netv129\bin\Release\ServiceStack.Logging.Log4Netv129.* release\ServiceStack.Logging\Log4Netv129
4+
COPY ..\src\ServiceStack.Logging.EventLog\bin\Release\ServiceStack.Logging.Elmah.* release\ServiceStack.Logging\Elmah
45
COPY ..\lib\log4net.1.2.9.dll release\ServiceStack.Logging\Log4Netv129\
56
COPY ..\lib\log4net.dll release\ServiceStack.Logging\Log4Net\
7+
COPY ..\lib\Elmah.dll release\ServiceStack.Logging\Elmah\
68
COPY ..\lib\ServiceStack.Interfaces.dll release\ServiceStack.Logging\
79

lib/Elmah.dll

172 KB
Binary file not shown.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using System;
2+
using System.Web;
3+
using Elmah;
4+
5+
namespace ServiceStack.Logging.Elmah
6+
{
7+
/// <summary> Writes Elmah intercepting logger. </summary>
8+
/// <remarks> 9/2/2011. </remarks>
9+
public class ElmahInterceptingLogger
10+
: ILog
11+
{
12+
private readonly ILog _log;
13+
private readonly ErrorLog _errorLog;
14+
15+
/// <summary> Constructor. </summary>
16+
/// <remarks>
17+
/// Logs to Elmahs ErrorLog.GetDefault. Only Error and Fatal are passed along to Elmah, while all other errors will be written to the
18+
/// wrapped logger.
19+
/// </remarks>
20+
/// <param name="log"> The underlying log to write to. </param>
21+
///
22+
/// <exception cref="ArgumentNullException"> Thrown when the wrapped log is null. </exception>
23+
public ElmahInterceptingLogger(ILog log)
24+
: this(log, ErrorLog.GetDefault(HttpContext.Current))
25+
{ }
26+
27+
/// <summary> Constructor. </summary>
28+
/// <remarks>
29+
/// Logs to the given Elmah ErrorLog. Only Error and Fatal are passed along to Elmah, while all other errors will be written to the
30+
/// wrapped logger.
31+
/// </remarks>
32+
/// <exception cref="ArgumentNullException"> Thrown when either the wrapped ILog or Elmah ErrorLog are null. </exception>
33+
/// <param name="log"> The underlying log to write to. </param>
34+
/// <param name="errorLog"> The error log. </param>
35+
public ElmahInterceptingLogger(ILog log, ErrorLog errorLog)
36+
{
37+
if (null == log) { throw new ArgumentNullException("log"); }
38+
if (null == errorLog) { throw new ArgumentNullException("errorLog"); }
39+
40+
_log = log;
41+
_errorLog = errorLog;
42+
}
43+
44+
public void Debug(object message, Exception exception)
45+
{
46+
_log.Debug(message, exception);
47+
}
48+
49+
public void Debug(object message)
50+
{
51+
_log.Debug(message);
52+
}
53+
54+
public void DebugFormat(string format, params object[] args)
55+
{
56+
_log.DebugFormat(format, args);
57+
}
58+
59+
public void Error(object message, Exception exception)
60+
{
61+
_errorLog.Log(new Error(exception, HttpContext.Current));
62+
_log.Error(message, exception);
63+
}
64+
65+
public void Error(object message)
66+
{
67+
_errorLog.Log(new Error(new System.ApplicationException(message.ToString()), HttpContext.Current));
68+
_log.Error(message);
69+
}
70+
71+
public void ErrorFormat(string format, params object[] args)
72+
{
73+
_errorLog.Log(new Error(new System.ApplicationException(string.Format(format, args)), HttpContext.Current));
74+
_log.ErrorFormat(format, args);
75+
}
76+
77+
public void Fatal(object message, Exception exception)
78+
{
79+
_errorLog.Log(new Error(exception, HttpContext.Current));
80+
_log.Fatal(message, exception);
81+
}
82+
83+
public void Fatal(object message)
84+
{
85+
_errorLog.Log(new Error(new System.ApplicationException(message.ToString()), HttpContext.Current));
86+
_log.Fatal(message);
87+
}
88+
89+
public void FatalFormat(string format, params object[] args)
90+
{
91+
_errorLog.Log(new Error(new System.ApplicationException(string.Format(format, args)), HttpContext.Current));
92+
_log.FatalFormat(format, args);
93+
}
94+
95+
public void Info(object message, Exception exception)
96+
{
97+
_log.Info(message, exception);
98+
}
99+
100+
public void Info(object message)
101+
{
102+
_log.Info(message);
103+
}
104+
105+
public void InfoFormat(string format, params object[] args)
106+
{
107+
_log.InfoFormat(format, args);
108+
}
109+
110+
public bool IsDebugEnabled
111+
{
112+
get { return _log.IsDebugEnabled; }
113+
}
114+
115+
public void Warn(object message, Exception exception)
116+
{
117+
_log.Warn(message, exception);
118+
}
119+
120+
public void Warn(object message)
121+
{
122+
_log.Warn(message);
123+
}
124+
125+
public void WarnFormat(string format, params object[] args)
126+
{
127+
_log.WarnFormat(format, args);
128+
}
129+
}
130+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
3+
namespace ServiceStack.Logging.Elmah
4+
{
5+
/// <summary>
6+
/// Elmah log factory that wraps another log factory, providing interception facilities on log calls. For Error or Fatal calls, the
7+
/// details will be logged to Elmah in addition to the originally intended logger. For all other log types, only the original logger is
8+
/// used.
9+
/// </summary>
10+
/// <remarks> 9/2/2011. </remarks>
11+
public class ElmahLogFactory : ILogFactory
12+
{
13+
private readonly ILogFactory _logFactory;
14+
15+
/// <summary> Constructor. </summary>
16+
/// <remarks> 9/2/2011. </remarks>
17+
/// <param name="logFactory"> The log factory that provides the original . </param>
18+
public ElmahLogFactory(ILogFactory logFactory)
19+
{
20+
if (null == logFactory) { throw new ArgumentNullException("logFactory"); }
21+
22+
_logFactory = logFactory;
23+
}
24+
25+
/// <summary> Gets a logger from the wrapped logFactory. </summary>
26+
/// <remarks> 9/2/2011. </remarks>
27+
/// <param name="typeName"> Name of the type. </param>
28+
/// <returns> The logger. </returns>
29+
public ILog GetLogger(string typeName)
30+
{
31+
return new ElmahInterceptingLogger(_logFactory.GetLogger(typeName));
32+
}
33+
34+
/// <summary> Gets a logger from the wrapped logFactory. </summary>
35+
/// <remarks> 9/2/2011. </remarks>
36+
/// <param name="type"> The type. </param>
37+
/// <returns> The logger. </returns>
38+
public ILog GetLogger(Type type)
39+
{
40+
return new ElmahInterceptingLogger(_logFactory.GetLogger(type));
41+
}
42+
}
43+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("ServiceStack.Logging.Elmah")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("ServiceStack")]
12+
[assembly: AssemblyProduct("ServiceStack.Logging.Elmah")]
13+
[assembly: AssemblyCopyright("Copyright © ServiceStack 2011")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("ae1c5e8f-160c-45fc-ba1c-da65f6e01d25")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6+
<ProductVersion>8.0.30703</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{EE43BF1E-CF97-4215-A5A3-46D1C363F928}</ProjectGuid>
9+
<OutputType>Library</OutputType>
10+
<AppDesignerFolder>Properties</AppDesignerFolder>
11+
<RootNamespace>ServiceStack.Logging.Elmah</RootNamespace>
12+
<AssemblyName>ServiceStack.Logging.Elmah</AssemblyName>
13+
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
14+
<FileAlignment>512</FileAlignment>
15+
<TargetFrameworkProfile />
16+
</PropertyGroup>
17+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
26+
</PropertyGroup>
27+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>bin\Release\</OutputPath>
31+
<DefineConstants>TRACE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
34+
</PropertyGroup>
35+
<ItemGroup>
36+
<Reference Include="Elmah">
37+
<HintPath>..\..\lib\Elmah.dll</HintPath>
38+
</Reference>
39+
<Reference Include="ServiceStack.Interfaces">
40+
<HintPath>..\..\lib\ServiceStack.Interfaces.dll</HintPath>
41+
</Reference>
42+
<Reference Include="System" />
43+
<Reference Include="System.Web" />
44+
</ItemGroup>
45+
<ItemGroup>
46+
<Compile Include="ElmahInterceptingLogger.cs" />
47+
<Compile Include="ElmahLogFactory.cs" />
48+
<Compile Include="Properties\AssemblyInfo.cs" />
49+
</ItemGroup>
50+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
51+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
52+
Other similar extension points exist, see Microsoft.Common.targets.
53+
<Target Name="BeforeBuild">
54+
</Target>
55+
<Target Name="AfterBuild">
56+
</Target>
57+
-->
58+
</Project>

src/ServiceStack.Logging.sln

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.Logging.Tests"
1111
EndProject
1212
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.Logging.NLog", "ServiceStack.Logging.NLog\ServiceStack.Logging.NLog.csproj", "{6B31F200-073C-46D4-B389-05646E035939}"
1313
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceStack.Logging.Elmah", "ServiceStack.Logging.Elmah\ServiceStack.Logging.Elmah.csproj", "{EE43BF1E-CF97-4215-A5A3-46D1C363F928}"
15+
EndProject
1416
Global
15-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
16-
Debug|Any CPU = Debug|Any CPU
17-
Release|Any CPU = Release|Any CPU
18-
EndGlobalSection
19-
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20-
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21-
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Debug|Any CPU.Build.0 = Debug|Any CPU
22-
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Release|Any CPU.ActiveCfg = Release|Any CPU
23-
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Release|Any CPU.Build.0 = Release|Any CPU
24-
{6B31F200-073C-46D4-B389-05646E035939}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25-
{6B31F200-073C-46D4-B389-05646E035939}.Debug|Any CPU.Build.0 = Debug|Any CPU
26-
{6B31F200-073C-46D4-B389-05646E035939}.Release|Any CPU.ActiveCfg = Release|Any CPU
27-
{6B31F200-073C-46D4-B389-05646E035939}.Release|Any CPU.Build.0 = Release|Any CPU
28-
{C44A6E80-326E-4036-8906-62E881F4727D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29-
{C44A6E80-326E-4036-8906-62E881F4727D}.Debug|Any CPU.Build.0 = Debug|Any CPU
30-
{C44A6E80-326E-4036-8906-62E881F4727D}.Release|Any CPU.ActiveCfg = Release|Any CPU
31-
{C44A6E80-326E-4036-8906-62E881F4727D}.Release|Any CPU.Build.0 = Release|Any CPU
32-
{D920BA88-E394-4C75-94E3-78D7298A8457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33-
{D920BA88-E394-4C75-94E3-78D7298A8457}.Debug|Any CPU.Build.0 = Debug|Any CPU
34-
{D920BA88-E394-4C75-94E3-78D7298A8457}.Release|Any CPU.ActiveCfg = Release|Any CPU
35-
{D920BA88-E394-4C75-94E3-78D7298A8457}.Release|Any CPU.Build.0 = Release|Any CPU
36-
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37-
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
38-
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
39-
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Release|Any CPU.Build.0 = Release|Any CPU
40-
EndGlobalSection
41-
GlobalSection(MonoDevelopProperties) = preSolution
42-
StartupItem = ServiceStack.Logging.EventLog\ServiceStack.Logging.EventLog.csproj
43-
EndGlobalSection
4417
GlobalSection(TeamFoundationVersionControl) = preSolution
4518
SccNumberOfProjects = 6
4619
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
@@ -62,7 +35,40 @@ Global
6235
SccProjectName5 = Bbc.Ww.Services.Logging.EventLog
6336
SccLocalPath5 = Bbc.Ww.Services.Logging.EventLog
6437
EndGlobalSection
38+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
39+
Debug|Any CPU = Debug|Any CPU
40+
Release|Any CPU = Release|Any CPU
41+
EndGlobalSection
42+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
43+
{D920BA88-E394-4C75-94E3-78D7298A8457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44+
{D920BA88-E394-4C75-94E3-78D7298A8457}.Debug|Any CPU.Build.0 = Debug|Any CPU
45+
{D920BA88-E394-4C75-94E3-78D7298A8457}.Release|Any CPU.ActiveCfg = Release|Any CPU
46+
{D920BA88-E394-4C75-94E3-78D7298A8457}.Release|Any CPU.Build.0 = Release|Any CPU
47+
{C44A6E80-326E-4036-8906-62E881F4727D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
48+
{C44A6E80-326E-4036-8906-62E881F4727D}.Debug|Any CPU.Build.0 = Debug|Any CPU
49+
{C44A6E80-326E-4036-8906-62E881F4727D}.Release|Any CPU.ActiveCfg = Release|Any CPU
50+
{C44A6E80-326E-4036-8906-62E881F4727D}.Release|Any CPU.Build.0 = Release|Any CPU
51+
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
52+
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Debug|Any CPU.Build.0 = Debug|Any CPU
53+
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Release|Any CPU.ActiveCfg = Release|Any CPU
54+
{0E1FF796-55CF-4F9B-BA72-484FC9D65065}.Release|Any CPU.Build.0 = Release|Any CPU
55+
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
56+
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
57+
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
58+
{DDDA27EC-5855-4E89-9971-C117EC08BDE3}.Release|Any CPU.Build.0 = Release|Any CPU
59+
{6B31F200-073C-46D4-B389-05646E035939}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
60+
{6B31F200-073C-46D4-B389-05646E035939}.Debug|Any CPU.Build.0 = Debug|Any CPU
61+
{6B31F200-073C-46D4-B389-05646E035939}.Release|Any CPU.ActiveCfg = Release|Any CPU
62+
{6B31F200-073C-46D4-B389-05646E035939}.Release|Any CPU.Build.0 = Release|Any CPU
63+
{EE43BF1E-CF97-4215-A5A3-46D1C363F928}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
64+
{EE43BF1E-CF97-4215-A5A3-46D1C363F928}.Debug|Any CPU.Build.0 = Debug|Any CPU
65+
{EE43BF1E-CF97-4215-A5A3-46D1C363F928}.Release|Any CPU.ActiveCfg = Release|Any CPU
66+
{EE43BF1E-CF97-4215-A5A3-46D1C363F928}.Release|Any CPU.Build.0 = Release|Any CPU
67+
EndGlobalSection
6568
GlobalSection(SolutionProperties) = preSolution
6669
HideSolutionNode = FALSE
6770
EndGlobalSection
71+
GlobalSection(MonoDevelopProperties) = preSolution
72+
StartupItem = ServiceStack.Logging.EventLog\ServiceStack.Logging.EventLog.csproj
73+
EndGlobalSection
6874
EndGlobal

tests/ServiceStack.Logging.Tests/ServiceStack.Logging.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@
8484
<ItemGroup>
8585
<Compile Include="Properties\AssemblyInfo.cs" />
8686
<Compile Include="Support\TestBase.cs" />
87+
<Compile Include="UnitTests\ElmahInterceptingLoggerTests.cs" />
88+
<Compile Include="UnitTests\ElmahLogFactoryTest.cs" />
8789
<Compile Include="UnitTests\EventLoggerTests.cs" />
8890
<Compile Include="UnitTests\EventLogFactoryTests.cs" />
8991
<Compile Include="UnitTests\DebugLoggerTests.cs" />
@@ -123,6 +125,10 @@
123125
</BootstrapperPackage>
124126
</ItemGroup>
125127
<ItemGroup>
128+
<ProjectReference Include="..\..\src\ServiceStack.Logging.Elmah\ServiceStack.Logging.Elmah.csproj">
129+
<Project>{EE43BF1E-CF97-4215-A5A3-46D1C363F928}</Project>
130+
<Name>ServiceStack.Logging.Elmah</Name>
131+
</ProjectReference>
126132
<ProjectReference Include="..\..\src\ServiceStack.Logging.EventLog\ServiceStack.Logging.EventLog.csproj">
127133
<Project>{D920BA88-E394-4C75-94E3-78D7298A8457}</Project>
128134
<Name>ServiceStack.Logging.EventLog</Name>

0 commit comments

Comments
 (0)