-
Notifications
You must be signed in to change notification settings - Fork 357
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
22 changed files
with
313 additions
and
116 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
src/Microsoft.Azure.WebJobs.Host/Extensions/LogLevelExtensions.cs
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System.Diagnostics; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Microsoft.Azure.WebJobs.Host | ||
{ | ||
internal static class LogLevelExtensions | ||
{ | ||
internal static TraceLevel ToTraceLevel(this LogLevel logLevel) | ||
{ | ||
TraceLevel level = TraceLevel.Off; | ||
switch (logLevel) | ||
{ | ||
case LogLevel.Critical: | ||
case LogLevel.Error: | ||
level = TraceLevel.Error; | ||
break; | ||
|
||
case LogLevel.Trace: | ||
case LogLevel.Debug: | ||
level = TraceLevel.Verbose; | ||
break; | ||
|
||
case LogLevel.Information: | ||
level = TraceLevel.Info; | ||
break; | ||
|
||
case LogLevel.Warning: | ||
level = TraceLevel.Warning; | ||
break; | ||
|
||
default: | ||
break; | ||
} | ||
return level; | ||
} | ||
} | ||
} |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
159 changes: 159 additions & 0 deletions
159
src/Microsoft.Azure.WebJobs.ServiceBus/MessagingExceptionHandler.cs
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using Microsoft.Azure.WebJobs.Host; | ||
using Microsoft.Azure.WebJobs.Logging; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.ServiceBus.Messaging; | ||
|
||
namespace Microsoft.Azure.WebJobs.ServiceBus | ||
{ | ||
internal abstract class MessagingExceptionHandler | ||
{ | ||
private readonly TraceWriter _traceWriter; | ||
private readonly ILoggerFactory _loggerFactory; | ||
private string _source; | ||
|
||
public MessagingExceptionHandler(string source, TraceWriter traceWriter, ILoggerFactory loggerFactory = null) | ||
{ | ||
if (string.IsNullOrEmpty(source)) | ||
{ | ||
throw new ArgumentNullException(nameof(source)); | ||
} | ||
if (traceWriter == null) | ||
{ | ||
throw new ArgumentNullException(nameof(traceWriter)); | ||
} | ||
|
||
_source = source; | ||
_traceWriter = traceWriter; | ||
_loggerFactory = loggerFactory; | ||
} | ||
|
||
public static MessagingExceptionHandler Subscribe(EventProcessorOptions options, TraceWriter traceWriter, ILoggerFactory loggerFactory = null) | ||
{ | ||
var exceptionHandler = new EventHubExceptionHandler(options, traceWriter, loggerFactory); | ||
exceptionHandler.Subscribe(); | ||
return exceptionHandler; | ||
} | ||
|
||
public static MessagingExceptionHandler Subscribe(OnMessageOptions options, TraceWriter traceWriter, ILoggerFactory loggerFactory = null) | ||
{ | ||
var exceptionHandler = new ServiceBusExceptionHandler(options, traceWriter, loggerFactory); | ||
exceptionHandler.Subscribe(); | ||
return exceptionHandler; | ||
} | ||
|
||
public abstract void Subscribe(); | ||
|
||
public abstract void Unsubscribe(); | ||
|
||
protected void Handle(object sender, ExceptionReceivedEventArgs e) | ||
{ | ||
LogExceptionReceivedEvent(e); | ||
} | ||
|
||
internal void LogExceptionReceivedEvent(ExceptionReceivedEventArgs e) | ||
{ | ||
try | ||
{ | ||
var logger = _loggerFactory?.CreateLogger(LogCategories.Executor); | ||
string message = $"{_source} error (Action={e.Action}) : {e.Exception.ToString()}"; | ||
|
||
var logLevel = GetLogLevel(e.Exception); | ||
logger?.Log(logLevel, 0, message, e.Exception, (s, ex) => message); | ||
|
||
var traceEvent = new TraceEvent(logLevel.ToTraceLevel(), message, null, e.Exception); | ||
_traceWriter.Trace(traceEvent); | ||
} | ||
catch | ||
{ | ||
// best effort logging | ||
} | ||
} | ||
|
||
protected virtual LogLevel GetLogLevel(Exception ex) | ||
{ | ||
var mex = ex as MessagingException; | ||
if (!(ex is OperationCanceledException) && (mex == null || !mex.IsTransient)) | ||
{ | ||
// any non-transient exceptions or unknown exception types | ||
// we want to log as errors | ||
return LogLevel.Error; | ||
} | ||
else | ||
{ | ||
// transient messaging errors we log as verbose so we have a record | ||
// of them, but we don't treat them as actual errors | ||
return LogLevel.Information; | ||
} | ||
} | ||
|
||
private class EventHubExceptionHandler : MessagingExceptionHandler | ||
{ | ||
private readonly EventProcessorOptions _options; | ||
|
||
public EventHubExceptionHandler(EventProcessorOptions options, TraceWriter traceWriter, ILoggerFactory loggerFactory = null) | ||
: base("EventProcessorHost", traceWriter, loggerFactory) | ||
{ | ||
if (options == null) | ||
{ | ||
throw new ArgumentNullException(nameof(options)); | ||
} | ||
|
||
_options = options; | ||
} | ||
|
||
public override void Subscribe() | ||
{ | ||
_options.ExceptionReceived += Handle; | ||
} | ||
|
||
public override void Unsubscribe() | ||
{ | ||
_options.ExceptionReceived -= Handle; | ||
} | ||
|
||
protected override LogLevel GetLogLevel(Exception ex) | ||
{ | ||
if (ex is ReceiverDisconnectedException || | ||
ex is LeaseLostException) | ||
{ | ||
// For EventProcessorHost these exceptions can happen as part | ||
// of normal partition balancing across instances, so we want to | ||
// trace them, but not treat them as errors. | ||
return LogLevel.Information; | ||
} | ||
|
||
return base.GetLogLevel(ex); | ||
} | ||
} | ||
|
||
private class ServiceBusExceptionHandler : MessagingExceptionHandler | ||
{ | ||
private readonly OnMessageOptions _options; | ||
|
||
public ServiceBusExceptionHandler(OnMessageOptions options, TraceWriter traceWriter, ILoggerFactory loggerFactory = null) | ||
: base("MessageReceiver", traceWriter, loggerFactory) | ||
{ | ||
if (options == null) | ||
{ | ||
throw new ArgumentNullException(nameof(options)); | ||
} | ||
|
||
_options = options; | ||
} | ||
|
||
public override void Subscribe() | ||
{ | ||
_options.ExceptionReceived += Handle; | ||
} | ||
|
||
public override void Unsubscribe() | ||
{ | ||
_options.ExceptionReceived -= Handle; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.