Skip to content

Commit 121d503

Browse files
committed
add some logging
1 parent a9793de commit 121d503

6 files changed

Lines changed: 85 additions & 19 deletions

File tree

src/ThingSet.Client/ThingSetClient.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.IO;
1010
using System.Threading;
1111
using System.Threading.Tasks;
12+
using Microsoft.Extensions.Logging;
1213
using ThingSet.Client.Schema;
1314
using ThingSet.Common.Protocols;
1415
using ThingSet.Common.Protocols.Binary;
@@ -23,6 +24,8 @@ public class ThingSetClient : IThingSetClient
2324
{
2425
private static readonly TimeSpan LockTimeout = TimeSpan.FromSeconds(5);
2526

27+
private readonly ILogger? _logger;
28+
2629
private readonly IClientTransport _transport;
2730

2831
private readonly IThingSetSchemaProvider _schemaProvider;
@@ -32,20 +35,22 @@ public class ThingSetClient : IThingSetClient
3235

3336
private Action<uint, string?, object?>? _callback;
3437

35-
public ThingSetClient(IClientTransport transport) : this(transport, new DefaultThingSetSchemaProvider())
38+
public ThingSetClient(IClientTransport transport, ILogger? logger = null) : this(transport, new DefaultThingSetSchemaProvider(), logger)
3639
{
3740
}
3841

39-
public ThingSetClient(IClientTransport transport, ulong? targetNodeId) : this(transport, new DefaultThingSetSchemaProvider(), targetNodeId)
42+
public ThingSetClient(IClientTransport transport, ulong? targetNodeId, ILogger? logger = null) : this(transport, new DefaultThingSetSchemaProvider(), targetNodeId, logger)
4043
{
4144
}
4245

43-
public ThingSetClient(IClientTransport transport, IThingSetSchemaProvider schemaProvider) : this(transport, schemaProvider, null)
46+
public ThingSetClient(IClientTransport transport, IThingSetSchemaProvider schemaProvider, ILogger? logger = null) : this(transport, schemaProvider, null, logger)
4447
{
4548
}
4649

47-
public ThingSetClient(IClientTransport transport, IThingSetSchemaProvider schemaProvider, ulong? targetNodeId)
50+
public ThingSetClient(IClientTransport transport, IThingSetSchemaProvider schemaProvider, ulong? targetNodeId, ILogger? logger = null)
4851
{
52+
_logger = logger;
53+
4954
_transport = transport;
5055
_schemaProvider = schemaProvider;
5156
TargetNodeID = targetNodeId;
@@ -181,6 +186,14 @@ public IEnumerable<ThingSetNode> GetNodes(ThingSetNodeEnumerationOptions options
181186
write(writer);
182187
writer.Encode(span.Slice(1));
183188
length += 1 + writer.BytesWritten;
189+
if (TargetNodeID.HasValue)
190+
{
191+
_logger?.LogDebug($"Forwarding {action} request of length {length} to {TargetNodeID.Value:x} via {_transport.PeerAddress}");
192+
}
193+
else
194+
{
195+
_logger?.LogDebug($"Sending {action} request of length {length} to {_transport.PeerAddress}");
196+
}
184197
if (!Monitor.TryEnter(_lock, LockTimeout))
185198
{
186199
throw new TimeoutException("Timed out trying to send request.");
@@ -193,6 +206,7 @@ public IEnumerable<ThingSetNode> GetNodes(ThingSetNodeEnumerationOptions options
193206
}
194207
int read = _transport.Read(buffer);
195208
ThingSetResponse response = (ThingSetStatus)buffer[0];
209+
_logger?.LogDebug($"Received response of length {read} from {_transport.PeerAddress} with result {response}");
196210
if (response.Success)
197211
{
198212
CborReader reader = new CborReader(buffer.AsMemory().Slice(1, read - 1), CborConformanceMode.Lax, allowMultipleRootLevelValues: true);
@@ -244,6 +258,7 @@ private void EnsureSchema()
244258
if (_schema.IsEmpty)
245259
{
246260
_schema = _schemaProvider.GetSchema(this);
261+
_logger?.LogDebug($"Retrieved {(_schema.IsEmpty ? "empty " : String.Empty)}schema from {_transport.PeerAddress}");
247262
}
248263
}
249264
}

src/ThingSet.Common.Transports.Can/CanClientTransport.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Formats.Cbor;
1010
using System.Threading;
1111
using System.Threading.Tasks;
12+
using Microsoft.Extensions.Logging;
1213
using SocketCANSharp;
1314
using SocketCANSharp.Network;
1415

@@ -36,14 +37,16 @@ public class CanClientTransport : ClientTransportBase<byte>, IClientTransport
3637
private readonly byte _destinationBridge;
3738
private readonly byte _destinationNodeAddress;
3839

39-
private readonly CanReportParser _reportParser = new CanReportParser();
40+
private readonly CanReportParser _reportParser;
4041

41-
public CanClientTransport(ThingSetCanInterface canInterface, byte destinationNodeAddress, bool leaveOpen) : this(canInterface, CanID.LocalBridge, destinationNodeAddress, leaveOpen)
42+
public CanClientTransport(ThingSetCanInterface canInterface, byte destinationNodeAddress, bool leaveOpen, ILogger? logger = null) : this(canInterface, CanID.LocalBridge, destinationNodeAddress, leaveOpen, logger)
4243
{
4344
}
4445

45-
public CanClientTransport(ThingSetCanInterface canInterface, byte destinationBridge, byte destinationNodeAddress, bool leaveOpen)
46+
public CanClientTransport(ThingSetCanInterface canInterface, byte destinationBridge, byte destinationNodeAddress, bool leaveOpen, ILogger? logger = null) : base(logger: logger)
4647
{
48+
_reportParser = new CanReportParser(logger);
49+
4750
_canInterface = canInterface;
4851
_disposeInterface = !leaveOpen;
4952

@@ -65,7 +68,7 @@ public CanClientTransport(ThingSetCanInterface canInterface, byte destinationBri
6568
_canFrameReader = canInterface.IsFdMode ? ReadCanFdFrame : ReadCanFrame;
6669
}
6770

68-
protected override string Address => $"{_destinationNodeAddress:x}";
71+
public override string PeerAddress => $"{_destinationNodeAddress:x}";
6972

7073
public override ValueTask ConnectAsync()
7174
{
@@ -151,7 +154,7 @@ protected override ValueTask HandleIncomingPublicationsAsync()
151154
byte sequenceNumber = CanID.GetSequenceNumber(canId);
152155
byte messageNumber = CanID.GetMessageNumber(canId);
153156
byte source = CanID.GetSource(canId);
154-
ReceiveBuffer buffer = _buffersBySender.GetOrAdd(source, _ => new ReceiveBuffer());
157+
ReceiveBuffer buffer = GetOrCreateBuffer(source);
155158
if (_reportParser.TryParse(sequenceNumber, messageNumber, type, buffer, data, out ulong? eui, out CborReader? reader))
156159
{
157160
NotifyReport(eui, reader);
@@ -208,6 +211,10 @@ private void NotifyControl(uint canId, ReadOnlyMemory<byte> body)
208211

209212
private class CanReportParser : ReportParser<MultiFrameMessageType>
210213
{
214+
public CanReportParser(ILogger? logger) : base(logger)
215+
{
216+
}
217+
211218
protected override bool IsFirst(MultiFrameMessageType type)
212219
{
213220
return type == MultiFrameMessageType.First || type == MultiFrameMessageType.Last;

src/ThingSet.Common.Transports.Ip/IpClientTransport.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Net;
88
using System.Net.Sockets;
99
using System.Threading.Tasks;
10+
using Microsoft.Extensions.Logging;
1011
using static ThingSet.Common.Transports.Ip.Protocol;
1112

1213
namespace ThingSet.Common.Transports.Ip;
@@ -22,21 +23,23 @@ public class IpClientTransport : ClientTransportBase<IPEndPoint>, IClientTranspo
2223
private readonly TcpClient _tcpClient;
2324
private readonly UdpClient _udpClient;
2425

25-
private readonly UdpReportParser _reportParser = new UdpReportParser();
26+
private readonly UdpReportParser _reportParser;
2627

27-
public IpClientTransport(string hostname) : this(hostname, Protocol.RequestResponsePort)
28+
public IpClientTransport(string hostname, ILogger? logger = null) : this(hostname, Protocol.RequestResponsePort, logger)
2829
{
2930
}
3031

31-
public IpClientTransport(string hostname, int port)
32+
public IpClientTransport(string hostname, int port, ILogger? logger = null) : base(logger: logger)
3233
{
34+
_reportParser = new UdpReportParser(logger);
35+
3336
_hostname = hostname;
3437
_port = port;
3538
_tcpClient = new TcpClient();
3639
_udpClient = new UdpClient();
3740
}
3841

39-
protected override string Address => _hostname;
42+
public override string PeerAddress => _hostname;
4043

4144
public async override ValueTask ConnectAsync()
4245
{
@@ -75,7 +78,7 @@ protected async override ValueTask HandleIncomingPublicationsAsync()
7578
MessageType messageType = (MessageType)(result.Buffer[0] & 0xF0);
7679
byte sequenceNumber = (byte)(result.Buffer[0] & 0x0F);
7780
byte messageNumber = result.Buffer[1];
78-
ReceiveBuffer buffer = _buffersBySender.GetOrAdd(result.RemoteEndPoint, _ => new ReceiveBuffer());
81+
ReceiveBuffer buffer = GetOrCreateBuffer(result.RemoteEndPoint);
7982
if (_reportParser.TryParse(sequenceNumber, messageNumber, messageType, buffer, result.Buffer, out ulong? eui, out CborReader? reader))
8083
{
8184
NotifyReport(eui, reader);
@@ -88,6 +91,10 @@ protected async override ValueTask HandleIncomingPublicationsAsync()
8891

8992
private class UdpReportParser : ReportParser<MessageType>
9093
{
94+
public UdpReportParser(ILogger? logger) : base(logger)
95+
{
96+
}
97+
9198
protected override int Offset => 2;
9299

93100
protected override bool IsFirst(MessageType type)

src/ThingSet.Common/ThingSet.Common.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
</PropertyGroup>
1717

1818
<ItemGroup>
19+
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
1920
<PackageReference Include="System.Formats.Cbor" Version="10.0.0" />
2021
</ItemGroup>
2122

src/ThingSet.Common/Transports/ClientTransportBase.cs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Formats.Cbor;
1010
using System.Threading;
1111
using System.Threading.Tasks;
12+
using Microsoft.Extensions.Logging;
1213
using ThingSet.Common.Protocols.Binary;
1314

1415
namespace ThingSet.Common.Transports;
@@ -22,24 +23,31 @@ public abstract class ClientTransportBase<TEndpoint> : IClientTransport
2223
{
2324
protected readonly ConcurrentDictionary<TEndpoint, ReceiveBuffer> _buffersBySender = new ConcurrentDictionary<TEndpoint, ReceiveBuffer>();
2425

26+
private readonly ILogger? _logger;
27+
private readonly int _bufferSize;
28+
2529
private Action<ulong?, CborReader>? _callback;
2630

2731
private readonly Thread _subscriptionThread;
2832
private bool _runSubscriptionThread = true;
2933

30-
protected ClientTransportBase()
34+
protected ClientTransportBase(int bufferSize = 16384, ILogger? logger = null)
3135
{
36+
_logger = logger;
37+
_bufferSize = bufferSize;
38+
3239
_subscriptionThread = new Thread(RunSubscriptionThread)
3340
{
3441
IsBackground = true,
35-
Name = $"Subscription {Address}",
42+
Name = $"Subscription {PeerAddress}",
3643
};
3744
}
3845

3946
/// <summary>
40-
/// String representation of a network identifier.
47+
/// String representation of a network identifier for the peer device
48+
/// to which this client is connected.
4149
/// </summary>
42-
protected abstract string Address { get; }
50+
public abstract string PeerAddress { get; }
4351

4452
/// <summary>
4553
/// Connects this transport.
@@ -90,6 +98,12 @@ protected async void RunSubscriptionThread()
9098

9199
protected abstract ValueTask HandleIncomingPublicationsAsync();
92100

101+
protected ReceiveBuffer GetOrCreateBuffer(TEndpoint endpoint)
102+
{
103+
byte[] buffer = new byte[_bufferSize];
104+
return _buffersBySender.GetOrAdd(endpoint, _ => new ReceiveBuffer(buffer));
105+
}
106+
93107
protected void NotifyReport(ulong? eui, CborReader reader)
94108
{
95109
reader.ReadUInt32(); // subset ID
@@ -104,6 +118,13 @@ protected void NotifyReport(ulong? eui, CborReader reader)
104118
protected abstract class ReportParser<TMessageType>
105119
where TMessageType : Enum
106120
{
121+
private readonly ILogger? _logger;
122+
123+
protected ReportParser(ILogger? logger)
124+
{
125+
_logger = logger;
126+
}
127+
107128
/// <returns>True if a complete message has been assembled.</returns>
108129
public bool TryParse(byte sequenceNumber, byte messageNumber, TMessageType messageType,
109130
ReceiveBuffer buffer, byte[] data, [MaybeNullWhen(true)] out ulong? eui,
@@ -116,14 +137,17 @@ public bool TryParse(byte sequenceNumber, byte messageNumber, TMessageType messa
116137
{
117138
buffer.Started = true;
118139
buffer.MessageNumber = messageNumber;
140+
_logger?.LogDebug($"Message {messageNumber} started");
119141
}
120142
else if (buffer.MessageNumber != messageNumber)
121143
{
144+
_logger?.LogDebug($"Message {messageNumber} mismatch; expected {buffer.MessageNumber}");
122145
buffer.Reset();
123146
return false;
124147
}
125148
else if (!buffer.Started)
126149
{
150+
_logger?.LogDebug($"Message unexpected");
127151
buffer.Reset();
128152
return false;
129153
}
@@ -135,6 +159,7 @@ public bool TryParse(byte sequenceNumber, byte messageNumber, TMessageType messa
135159
}
136160
if (IsLast(messageType))
137161
{
162+
_logger?.LogDebug($"Dispatching message {messageNumber} of length {buffer.Position}");
138163
ReadOnlyMemory<byte> memory = buffer.Buffer;
139164
reader = new CborReader(memory.Slice(1), CborConformanceMode.Lax, allowMultipleRootLevelValues: true);
140165
if (buffer.Buffer[0] == (byte)ThingSetRequest.ReportEnhanced)
@@ -156,7 +181,12 @@ public bool TryParse(byte sequenceNumber, byte messageNumber, TMessageType messa
156181

157182
protected class ReceiveBuffer
158183
{
159-
public byte[] Buffer = new byte[32768];
184+
public ReceiveBuffer(byte[] buffer)
185+
{
186+
Buffer = buffer;
187+
}
188+
189+
public byte[] Buffer;
160190
public int Position;
161191
public byte Sequence;
162192
public byte MessageNumber;

src/ThingSet.Common/Transports/IClientTransport.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ namespace ThingSet.Common.Transports;
1414
/// </summary>
1515
public interface IClientTransport : ITransport
1616
{
17+
/// <summary>
18+
/// String representation of a network identifier for the peer device
19+
/// to which this client is connected.
20+
/// </summary>
21+
string PeerAddress { get; }
22+
1723
ValueTask ConnectAsync();
1824
/// <summary>
1925
/// Subscribes for asynchronous reports delivered via this

0 commit comments

Comments
 (0)