Improve and unity logging

This commit is contained in:
Peter Butzhammer
2024-07-30 10:09:53 +02:00
parent 8836c14e2b
commit 79031d6f1c
2 changed files with 29 additions and 20 deletions

View File

@@ -35,16 +35,20 @@ internal class Sharp7Connector: IDisposable
rackNr = settings.RackNumber; rackNr = settings.RackNumber;
ReconnectDelay = TimeSpan.FromSeconds(5); ReconnectDelay = TimeSpan.FromSeconds(5);
ConnectionIdentifier = $"{ipAddress}:{port} Cpu {cpuSlotNr} Rack {rackNr}";
} }
public IObservable<ConnectionState> ConnectionState => connectionStateSubject.DistinctUntilChanged().AsObservable(); public IObservable<ConnectionState> ConnectionState => connectionStateSubject.DistinctUntilChanged().AsObservable();
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public TimeSpan ReconnectDelay { get; set; } private string ConnectionIdentifier { get; }
private bool IsConnected => connectionStateSubject.Value == Enums.ConnectionState.Connected; private bool IsConnected => connectionStateSubject.Value == Enums.ConnectionState.Connected;
private TimeSpan ReconnectDelay { get; }
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
@@ -67,13 +71,13 @@ internal class Sharp7Connector: IDisposable
else else
{ {
var errorText = EvaluateErrorCode(errorCode); var errorText = EvaluateErrorCode(errorCode);
Logger.LogError("Failed to establish initial connection: {Error}", errorText); Logger.LogError("Failed to establish initial connection to {Connection}: {Error}", ConnectionIdentifier, errorText);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
connectionStateSubject.OnNext(Enums.ConnectionState.ConnectionLost); connectionStateSubject.OnNext(Enums.ConnectionState.ConnectionLost);
Logger.LogError(ex, "Failed to establish initial connection."); Logger.LogError(ex, "Failed to establish initial connection ro {Connection}.", ConnectionIdentifier);
} }
return false; return false;
@@ -125,14 +129,14 @@ internal class Sharp7Connector: IDisposable
.Take(1) .Take(1)
.SelectMany(_ => Reconnect()) .SelectMany(_ => Reconnect())
.RepeatAfterDelay(ReconnectDelay) .RepeatAfterDelay(ReconnectDelay)
.LogAndRetry(Logger, "Error while reconnecting to S7.") .LogAndRetry(Logger, $"Error while reconnecting to {ConnectionIdentifier}.")
.Subscribe(); .Subscribe();
disposables.Add(subscription); disposables.Add(subscription);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger?.LogError(ex, "S7 driver could not be initialized"); Logger?.LogError(ex, "S7 driver for {Connection} could not be initialized", ConnectionIdentifier);
} }
return Task.FromResult(true); return Task.FromResult(true);
@@ -149,11 +153,13 @@ internal class Sharp7Connector: IDisposable
await Task.Factory.StartNew(() => sharp7.ReadArea(operand.ToArea(), dbNo, startByteAddress, bytesToRead, S7WordLength.Byte, buffer), token, TaskCreationOptions.None, scheduler); await Task.Factory.StartNew(() => sharp7.ReadArea(operand.ToArea(), dbNo, startByteAddress, bytesToRead, S7WordLength.Byte, buffer), token, TaskCreationOptions.None, scheduler);
token.ThrowIfCancellationRequested(); token.ThrowIfCancellationRequested();
EnsureSuccessOrThrow(result, $"Error reading {operand}{dbNo}:{startByteAddress}->{bytesToRead}"); EnsureSuccessOrThrow(result, $"Error reading {operand}{dbNo}:{startByteAddress} ({bytesToRead} bytes)");
return buffer; return buffer;
} }
public override string ToString() => ConnectionIdentifier;
public async Task WriteBit(Operand operand, ushort startByteAddress, byte bitAdress, bool value, ushort dbNo, CancellationToken token) public async Task WriteBit(Operand operand, ushort startByteAddress, byte bitAdress, bool value, ushort dbNo, CancellationToken token)
{ {
EnsureConnectionValid(); EnsureConnectionValid();
@@ -175,7 +181,7 @@ internal class Sharp7Connector: IDisposable
var result = await Task.Factory.StartNew(() => sharp7.WriteArea(operand.ToArea(), dbNo, startByteAddress, bytesToWrite, S7WordLength.Byte, data), token, TaskCreationOptions.None, scheduler); var result = await Task.Factory.StartNew(() => sharp7.WriteArea(operand.ToArea(), dbNo, startByteAddress, bytesToWrite, S7WordLength.Byte, data), token, TaskCreationOptions.None, scheduler);
token.ThrowIfCancellationRequested(); token.ThrowIfCancellationRequested();
EnsureSuccessOrThrow(result, $"Error writing {operand}{dbNo}:{startByteAddress}.{data.Length}"); EnsureSuccessOrThrow(result, $"Error writing {operand}{dbNo}:{startByteAddress} ({data.Length} bytes)");
} }
@@ -222,18 +228,18 @@ internal class Sharp7Connector: IDisposable
throw new InvalidOperationException("Plc is not connected"); throw new InvalidOperationException("Plc is not connected");
} }
private void EnsureSuccessOrThrow(int result, string message) private void EnsureSuccessOrThrow(int errorCode, string message)
{ {
if (result == 0) return; if (errorCode == 0) return;
var errorText = EvaluateErrorCode(result); var errorText = EvaluateErrorCode(errorCode);
var completeMessage = $"{message}: {errorText}"; var completeMessage = $"{message}: {errorText}";
var additionalErrorText = S7ErrorCodes.GetAdditionalErrorText(result); var additionalErrorText = S7ErrorCodes.GetAdditionalErrorText(errorCode);
if (additionalErrorText != null) if (additionalErrorText != null)
completeMessage += Environment.NewLine + additionalErrorText; completeMessage += Environment.NewLine + additionalErrorText;
throw new S7CommunicationException(completeMessage, result, errorText); throw new S7CommunicationException(completeMessage, errorCode, errorText);
} }
private string EvaluateErrorCode(int errorCode) private string EvaluateErrorCode(int errorCode)
@@ -245,7 +251,6 @@ internal class Sharp7Connector: IDisposable
throw new InvalidOperationException("S7 driver is not initialized."); throw new InvalidOperationException("S7 driver is not initialized.");
var errorText = $"0x{errorCode:X}, {sharp7.ErrorText(errorCode)}"; var errorText = $"0x{errorCode:X}, {sharp7.ErrorText(errorCode)}";
Logger?.LogError($"S7 Error {errorText}");
if (S7ErrorCodes.AssumeConnectionLost(errorCode)) if (S7ErrorCodes.AssumeConnectionLost(errorCode))
SetConnectionLostState(); SetConnectionLostState();

View File

@@ -283,7 +283,7 @@ public class Sharp7Plc : IPlc
} }
catch (Exception e) catch (Exception e)
{ {
Logger?.LogError(e, "Intiial PLC connection failed."); // Ignore. Exception is logged in the connector
} }
}, token); }, token);
@@ -329,9 +329,12 @@ public class Sharp7Plc : IPlc
private void PrintAndResetPerformanceStatistik() private void PrintAndResetPerformanceStatistik()
{ {
if (performanceCounter.Count == performanceCounter.Capacity) if (performanceCounter.Count != performanceCounter.Capacity) return;
if (Logger.IsEnabled(LogLevel.Trace))
{ {
var average = performanceCounter.Average(); var average = performanceCounter.Average();
var min = performanceCounter.Min(); var min = performanceCounter.Min();
var max = performanceCounter.Max(); var max = performanceCounter.Max();
@@ -340,8 +343,9 @@ public class Sharp7Plc : IPlc
performanceCounter.Capacity, min, max, average, performanceCounter.Capacity, min, max, average,
multiVariableSubscriptions.ExistingKeys.Count(), multiVariableSubscriptions.ExistingKeys.Count(),
MultiVarRequestMaxItems); MultiVarRequestMaxItems);
performanceCounter.Clear();
} }
performanceCounter.Clear();
} }
private void StartNotificationLoop() private void StartNotificationLoop()
@@ -355,7 +359,7 @@ public class Sharp7Plc : IPlc
.FirstAsync(states => states == Enums.ConnectionState.Connected) .FirstAsync(states => states == Enums.ConnectionState.Connected)
.SelectMany(_ => GetAllValues(s7Connector)) .SelectMany(_ => GetAllValues(s7Connector))
.RepeatAfterDelay(MultiVarRequestCycleTime) .RepeatAfterDelay(MultiVarRequestCycleTime)
.LogAndRetryAfterDelay(Logger, MultiVarRequestCycleTime, "Error while getting batch notifications from plc") .LogAndRetryAfterDelay(Logger, MultiVarRequestCycleTime, $"Error while getting batch notifications from {s7Connector}")
.Subscribe(); .Subscribe();
if (Interlocked.CompareExchange(ref notificationSubscription, subscription, null) != null) if (Interlocked.CompareExchange(ref notificationSubscription, subscription, null) != null)