Skip to content

Commit

Permalink
Log threads (#379)
Browse files Browse the repository at this point in the history
* Improve catch

* Log mem and monitored items

* Log thread info

* Log min threads

* Update version

* Improve err handling
  • Loading branch information
luiscantero authored Jul 29, 2024
1 parent 5714b63 commit fb2b4a9
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 39 deletions.
16 changes: 13 additions & 3 deletions src/OpcPlcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ namespace OpcPlc;

public class OpcPlcServer
{
private const int DefaultMinThreads = 20;
private const int DefaultCompletionPortThreads = 20;

private string[] _args;
private CancellationTokenSource _cancellationTokenSource;
private ImmutableList<IPluginNodes> _pluginNodes;
Expand Down Expand Up @@ -87,9 +90,16 @@ public async Task StartAsync(string[] args, CancellationToken cancellationToken

LogLogo();

Logger.LogInformation("Current directory: {currentDirectory}", Directory.GetCurrentDirectory());
Logger.LogInformation("Log file: {logFileName}", Path.GetFullPath(Config.LogFileName));
Logger.LogInformation("Log level: {logLevel}", Config.LogLevelCli);
ThreadPool.SetMinThreads(DefaultMinThreads, DefaultCompletionPortThreads);
ThreadPool.GetMinThreads(out int minWorkerThreads, out int minCompletionPortThreads);
Logger.LogInformation(
"Min worker threads: {MinWorkerThreads}, min completion port threads: {MinCompletionPortThreads}",
minWorkerThreads,
minCompletionPortThreads);

Logger.LogInformation("Current directory: {CurrentDirectory}", Directory.GetCurrentDirectory());
Logger.LogInformation("Log file: {LogFileName}", Path.GetFullPath(Config.LogFileName));
Logger.LogInformation("Log level: {LogLevel}", Config.LogLevelCli);

// Show OPC PLC version.
var fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
Expand Down
159 changes: 124 additions & 35 deletions src/PlcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace OpcPlc;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;

Expand Down Expand Up @@ -50,10 +51,25 @@ public PlcServer(OpcPlcConfiguration config, PlcSimulation plcSimulation, TimeSe
(state) => {
try
{
var curProc = Process.GetCurrentProcess();

ThreadPool.GetAvailableThreads(out int availWorkerThreads, out int availCompletionPortThreads);

_logger.LogInformation(
"Open sessions: {Sessions}, open subscriptions: {Subscriptions}",
"\n\t# Open sessions: {Sessions}\n" +
"\t# Open subscriptions: {Subscriptions}\n" +
"\t# Monitored items: {MonitoredItems:N0}\n" +
"\t# Working set {WorkingSet:N0} MB\n" +
"\t# Available worker threads: {AvailWorkerThreads:N0}\n" +
"\t# Available completion port threads: {AvailCompletionPortThreads:N0}\n" +
"\t# Thread count: {ThreadCount:N0}",
ServerInternal.SessionManager.GetSessions().Count,
ServerInternal.SubscriptionManager.GetSubscriptions().Count);
ServerInternal.SubscriptionManager.GetSubscriptions().Count,
ServerInternal.SubscriptionManager.GetSubscriptions().Sum(s => s.MonitoredItemCount),
curProc.WorkingSet64 / 1024 / 1024,
availWorkerThreads,
availCompletionPortThreads,
curProc.Threads.Count);
}
catch
{
Expand Down Expand Up @@ -148,6 +164,9 @@ public override ResponseHeader CreateMonitoredItems(
out MonitoredItemCreateResultCollection results,
out DiagnosticInfoCollection diagnosticInfos)
{
results = default;
diagnosticInfos = default;

try
{
OperationContext context = ValidateRequest(requestHeader, RequestType.CreateMonitoredItems);
Expand All @@ -164,9 +183,43 @@ public override ResponseHeader CreateMonitoredItems(

return responseHeader;
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadNoSubscription)
{
MetricsHelper.RecordTotalErrors(nameof(CreateMonitoredItems));

_logger.LogDebug(
ex,
"Failed creating monitored items: {StatusCode}",
StatusCodes.BadNoSubscription.ToString());

return new ResponseHeader { ServiceResult = StatusCodes.BadNoSubscription };
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadSessionIdInvalid)
{
MetricsHelper.RecordTotalErrors(nameof(CreateMonitoredItems));

_logger.LogDebug(
ex,
"Failed creating monitored items: {StatusCode}",
StatusCodes.BadSessionIdInvalid.ToString());

return new ResponseHeader { ServiceResult = StatusCodes.BadSessionIdInvalid };
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadSecureChannelIdInvalid)
{
MetricsHelper.RecordTotalErrors(nameof(CreateMonitoredItems));

_logger.LogDebug(
ex,
"Failed creating monitored items: {StatusCode}",
StatusCodes.BadSecureChannelIdInvalid.ToString());

return new ResponseHeader { ServiceResult = StatusCodes.BadSecureChannelIdInvalid };
}
catch (Exception ex)
{
MetricsHelper.RecordTotalErrors(nameof(CreateMonitoredItems));

_logger.LogError(ex, "Error creating monitored items");
throw;
}
Expand All @@ -182,6 +235,13 @@ public override ResponseHeader Publish(
out StatusCodeCollection results,
out DiagnosticInfoCollection diagnosticInfos)
{
subscriptionId = default;
availableSequenceNumbers = default;
moreNotifications = default;
notificationMessage = default;
results = default;
diagnosticInfos = default;

try
{
OperationContext context = ValidateRequest(requestHeader, RequestType.Publish);
Expand Down Expand Up @@ -216,48 +276,40 @@ public override ResponseHeader Publish(

return responseHeader;
}
catch (ServiceResultException ex)
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadNoSubscription)
{
MetricsHelper.RecordTotalErrors(nameof(Publish));

subscriptionId = default;
availableSequenceNumbers = default;
moreNotifications = default;
notificationMessage = default;
results = default;
diagnosticInfos = default;

if (ex.StatusCode == StatusCodes.BadNoSubscription)
{
_logger.LogDebug(
"Failed to publish: {StatusCode}",
StatusCodes.BadNoSubscription.ToString());

return new ResponseHeader { ServiceResult = StatusCodes.BadNoSubscription };
}
_logger.LogDebug(
ex,
"Failed to publish: {StatusCode}",
StatusCodes.BadNoSubscription.ToString());

if (ex.StatusCode == StatusCodes.BadSessionIdInvalid)
{
_logger.LogDebug(
"Failed to publish: {StatusCode}",
StatusCodes.BadSessionIdInvalid.ToString());
return new ResponseHeader { ServiceResult = StatusCodes.BadNoSubscription };
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadSessionIdInvalid)
{
MetricsHelper.RecordTotalErrors(nameof(Publish));

return new ResponseHeader { ServiceResult = StatusCodes.BadSessionIdInvalid };
}
_logger.LogDebug(
ex,
"Failed to publish: {StatusCode}",
StatusCodes.BadSessionIdInvalid.ToString());

if (ex.StatusCode == StatusCodes.BadSecureChannelIdInvalid)
{
_logger.LogDebug(
"Failed to publish: {StatusCode}",
StatusCodes.BadSecureChannelIdInvalid.ToString());
return new ResponseHeader { ServiceResult = StatusCodes.BadSessionIdInvalid };
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadSecureChannelIdInvalid)
{
MetricsHelper.RecordTotalErrors(nameof(Publish));

return new ResponseHeader { ServiceResult = StatusCodes.BadSecureChannelIdInvalid };
}
_logger.LogDebug(
ex,
"Failed to publish: {StatusCode}",
StatusCodes.BadSecureChannelIdInvalid.ToString());

_logger.LogError(ex, "Error publishing");
throw;
return new ResponseHeader { ServiceResult = StatusCodes.BadSecureChannelIdInvalid };
}
catch(Exception ex)
catch (Exception ex)
{
MetricsHelper.RecordTotalErrors(nameof(Publish));

Expand All @@ -274,6 +326,9 @@ public override ResponseHeader Read(
out DataValueCollection results,
out DiagnosticInfoCollection diagnosticInfos)
{
results = default;
diagnosticInfos = default;

try
{
var responseHeader = base.Read(requestHeader, maxAge, timestampsToReturn, nodesToRead, out results, out diagnosticInfos);
Expand All @@ -282,9 +337,43 @@ public override ResponseHeader Read(

return responseHeader;
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadNoSubscription)
{
MetricsHelper.RecordTotalErrors(nameof(Read));

_logger.LogDebug(
ex,
"Failed to read: {StatusCode}",
StatusCodes.BadNoSubscription.ToString());

return new ResponseHeader { ServiceResult = StatusCodes.BadNoSubscription };
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadSessionIdInvalid)
{
MetricsHelper.RecordTotalErrors(nameof(Read));

_logger.LogDebug(
ex,
"Failed to read: {StatusCode}",
StatusCodes.BadSessionIdInvalid.ToString());

return new ResponseHeader { ServiceResult = StatusCodes.BadSessionIdInvalid };
}
catch (ServiceResultException ex) when (ex.StatusCode == StatusCodes.BadSecureChannelIdInvalid)
{
MetricsHelper.RecordTotalErrors(nameof(Read));

_logger.LogDebug(
ex,
"Failed to read: {StatusCode}",
StatusCodes.BadSecureChannelIdInvalid.ToString());

return new ResponseHeader { ServiceResult = StatusCodes.BadSecureChannelIdInvalid };
}
catch (Exception ex)
{
MetricsHelper.RecordTotalErrors(nameof(Read));

_logger.LogError(ex, "Error reading");
throw;
}
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "2.12.19",
"version": "2.12.20",
"versionHeightOffset": -1,
"publicReleaseRefSpec": [
"^refs/heads/main$",
Expand Down

0 comments on commit fb2b4a9

Please sign in to comment.