Merge pull request #52 from Azure/erichb_develop

Make tracing better
This commit is contained in:
Erich Barnstedt 2017-07-13 17:16:13 +02:00 коммит произвёл GitHub
Родитель a2c97b8770 2423d7f872
Коммит 68b9437d8a
3 изменённых файлов: 172 добавлений и 155 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -17,7 +17,8 @@
*.dll *.dll
*.so *.so
*.pdb *.pdb
/src/GatewayApp.NetCore/Logs
*.der *.der
*.exe *.exe
/src/out /src/out
/src/Logs

Просмотреть файл

@ -22,6 +22,19 @@ namespace Opc.Ua.Publisher
Configuration.ClientConfiguration = new ClientConfiguration(); Configuration.ClientConfiguration = new ClientConfiguration();
Configuration.ServerConfiguration = new ServerConfiguration(); Configuration.ServerConfiguration = new ServerConfiguration();
// enable logging
Configuration.TraceConfiguration = new TraceConfiguration();
Configuration.TraceConfiguration.TraceMasks = Utils.TraceMasks.Error | Utils.TraceMasks.Security | Utils.TraceMasks.StackTrace | Utils.TraceMasks.StartStop;
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_LOGP")))
{
Configuration.TraceConfiguration.OutputFilePath = Environment.GetEnvironmentVariable("_GW_LOGP");
}
else
{
Configuration.TraceConfiguration.OutputFilePath = "./Logs/" + Configuration.ApplicationName + ".log.txt";
}
Configuration.TraceConfiguration.ApplySettings();
if (Configuration.SecurityConfiguration == null) if (Configuration.SecurityConfiguration == null)
{ {
Configuration.SecurityConfiguration = new SecurityConfiguration(); Configuration.SecurityConfiguration = new SecurityConfiguration();
@ -161,15 +174,15 @@ namespace Opc.Ua.Publisher
newPolicy.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15; newPolicy.SecurityPolicyUri = SecurityPolicies.Basic128Rsa15;
Configuration.ServerConfiguration.SecurityPolicies.Add(newPolicy); Configuration.ServerConfiguration.SecurityPolicies.Add(newPolicy);
// enable logging
Configuration.TraceConfiguration = new TraceConfiguration();
Configuration.TraceConfiguration.TraceMasks = Utils.TraceMasks.Error | Utils.TraceMasks.Security | Utils.TraceMasks.StackTrace | Utils.TraceMasks.StartStop;
Configuration.TraceConfiguration.OutputFilePath = "./Logs/" + Configuration.ApplicationName + ".log.txt";
Configuration.TraceConfiguration.ApplySettings();
// the OperationTimeout should be twice the minimum value for PublishingInterval * KeepAliveCount, so set to 120s // the OperationTimeout should be twice the minimum value for PublishingInterval * KeepAliveCount, so set to 120s
Configuration.TransportQuotas.OperationTimeout = 120000; Configuration.TransportQuotas.OperationTimeout = 120000;
// allow SHA1 certificates for now as many OPC Servers still use them
Configuration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
// allow 1024 minimum key size as many OPC Servers still use them
Configuration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
// validate the configuration now // validate the configuration now
Configuration.Validate(Configuration.ApplicationType).Wait(); Configuration.Validate(Configuration.ApplicationType).Wait();
} }

Просмотреть файл

@ -29,192 +29,195 @@ namespace Opc.Ua.Publisher
/// </summary> /// </summary>
public static void Trace(string message, params object[] args) public static void Trace(string message, params object[] args)
{ {
Utils.Trace(message, args); Utils.Trace(Utils.TraceMasks.Error, message, args);
Console.WriteLine(message, args); Console.WriteLine(DateTime.Now.ToString() + ": " + message, args);
} }
public static void Trace(int traceMask, string format, params object[] args) public static void Trace(int traceMask, string format, params object[] args)
{ {
Utils.Trace(traceMask, format, args); Utils.Trace(traceMask, format, args);
Console.WriteLine(format, args); Console.WriteLine(DateTime.Now.ToString() + ": " + format, args);
} }
public static void Trace(Exception e, string format, params object[] args) public static void Trace(Exception e, string format, params object[] args)
{ {
Utils.Trace(e, format, args); Utils.Trace(e, format, args);
Console.WriteLine(e.ToString()); Console.WriteLine(DateTime.Now.ToString() + ": " + e.Message.ToString());
Console.WriteLine(format, args); Console.WriteLine(DateTime.Now.ToString() + ": " + format, args);
} }
public static void Main(string[] args) public static void Main(string[] args)
{ {
if ((args.Length == 0) || string.IsNullOrEmpty(args[0])) try
{ {
Console.WriteLine("Please specify an application name as argument!"); if ((args.Length == 0) || string.IsNullOrEmpty(args[0]))
return;
}
m_applicationName = args[0];
string ownerConnectionString = string.Empty;
// check if we also received an owner connection string
if ((args.Length > 1) && !string.IsNullOrEmpty(args[1]))
{
ownerConnectionString = args[1];
}
else
{
Trace("IoT Hub owner connection string not passed as argument.");
// check if we have an environment variable to register ourselves with IoT Hub
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS")))
{ {
ownerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS"); Trace("Please specify an application name as argument!");
} return;
}
// register ourselves with IoT Hub
if (ownerConnectionString != string.Empty)
{
Trace("Attemping to register ourselves with IoT Hub using owner connection string: " + ownerConnectionString);
RegistryManager manager = RegistryManager.CreateFromConnectionString(ownerConnectionString);
// remove any existing device
Device existingDevice = manager.GetDeviceAsync(m_applicationName).Result;
if (existingDevice != null)
{
manager.RemoveDeviceAsync(m_applicationName).Wait();
}
Device newDevice = manager.AddDeviceAsync(new Device(m_applicationName)).Result;
if (newDevice != null)
{
string hostname = ownerConnectionString.Substring(0, ownerConnectionString.IndexOf(";"));
string deviceConnectionString = hostname + ";DeviceId=" + m_applicationName + ";SharedAccessKey=" + newDevice.Authentication.SymmetricKey.PrimaryKey;
SecureIoTHubToken.Write(m_applicationName, deviceConnectionString);
} }
else else
{ {
Trace("Could not register ourselves with IoT Hub using owner connection string: " + ownerConnectionString); Trace("Publisher is starting up...");
} }
}
else
{
Trace("IoT Hub owner connection string not found, registration with IoT Hub abandoned.");
}
// try to read connection string from secure store and open IoTHub client m_applicationName = args[0];
Trace("Attemping to read connection string from secure store with certificate name: " + m_applicationName); ModuleConfiguration moduleConfiguration = new ModuleConfiguration(m_applicationName);
string connectionString = SecureIoTHubToken.Read(m_applicationName); m_configuration = moduleConfiguration.Configuration;
if (!string.IsNullOrEmpty(connectionString)) m_configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
{
Trace("Attemping to configure publisher with connection string: " + connectionString);
m_deviceClient = DeviceClient.CreateFromConnectionString(connectionString, Microsoft.Azure.Devices.Client.TransportType.Mqtt);
m_deviceClient.RetryPolicy = RetryPolicyType.Exponential_Backoff_With_Jitter;
m_deviceClient.OpenAsync().Wait();
}
else
{
Trace("Device connection string not found in secure store.");
}
ModuleConfiguration moduleConfiguration = new ModuleConfiguration(m_applicationName);
m_configuration = moduleConfiguration.Configuration;
m_configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
// update log configuration, if available // start our server interface
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_LOGP"))) try
{
m_configuration.TraceConfiguration.OutputFilePath = Environment.GetEnvironmentVariable("_GW_LOGP");
m_configuration.TraceConfiguration.ApplySettings();
}
// get a list of persisted endpoint URLs and create a session for each.
try
{
// check if we have an env variable specifying the published nodes path, otherwise use current directory
string publishedNodesFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "publishednodes.json";
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP")))
{ {
publishedNodesFilePath = Environment.GetEnvironmentVariable("_GW_PNFP"); Trace("Starting server on endpoint " + m_configuration.ServerConfiguration.BaseAddresses[0].ToString() + "...");
m_server.Start(m_configuration);
Trace("Server started.");
} }
catch (Exception ex)
Trace("Attemping to load nodes file from: " + publishedNodesFilePath);
m_nodesLookups = JsonConvert.DeserializeObject<PublishedNodesCollection>(File.ReadAllText(publishedNodesFilePath));
Trace("Loaded " + m_nodesLookups.Count.ToString() + " nodes.");
}
catch (Exception ex)
{
Trace("Nodes file loading failed with: " + ex.Message);
}
foreach (NodeLookup nodeLookup in m_nodesLookups)
{
if (!m_endpointUrls.Contains(nodeLookup.EndPointURL))
{ {
m_endpointUrls.Add(nodeLookup.EndPointURL); Trace("Starting server failed with: " + ex.Message);
} }
}
// start the server // check if we also received an owner connection string
try string ownerConnectionString = string.Empty;
{ if ((args.Length > 1) && !string.IsNullOrEmpty(args[1]))
Trace("Starting server on endpoint " + m_configuration.ServerConfiguration.BaseAddresses[0].ToString() + "...");
m_server.Start(m_configuration);
Trace("Server started.");
}
catch (Exception ex)
{
Trace("Starting server failed with: " + ex.Message);
}
// connect to servers
Trace("Attemping to connect to servers...");
try
{
List<Task> connectionAttempts = new List<Task>();
foreach (Uri endpointUrl in m_endpointUrls)
{ {
Trace("Connecting to server: " + endpointUrl); ownerConnectionString = args[1];
connectionAttempts.Add(EndpointConnect(endpointUrl)); }
else
{
Trace("IoT Hub owner connection string not passed as argument.");
// check if we have an environment variable to register ourselves with IoT Hub
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS")))
{
ownerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS");
}
} }
// Wait for all sessions to be connected // register ourselves with IoT Hub
Task.WaitAll(connectionAttempts.ToArray()); if (ownerConnectionString != string.Empty)
} {
catch (Exception ex) Trace("Attemping to register ourselves with IoT Hub using owner connection string: " + ownerConnectionString);
{ RegistryManager manager = RegistryManager.CreateFromConnectionString(ownerConnectionString);
Trace("Exception: " + ex.ToString() + "\r\n" + ex.InnerException != null ? ex.InnerException.ToString() : null);
} // remove any existing device
Device existingDevice = manager.GetDeviceAsync(m_applicationName).Result;
if (existingDevice != null)
{
manager.RemoveDeviceAsync(m_applicationName).Wait();
}
Device newDevice = manager.AddDeviceAsync(new Device(m_applicationName)).Result;
if (newDevice != null)
{
string hostname = ownerConnectionString.Substring(0, ownerConnectionString.IndexOf(";"));
string deviceConnectionString = hostname + ";DeviceId=" + m_applicationName + ";SharedAccessKey=" + newDevice.Authentication.SymmetricKey.PrimaryKey;
SecureIoTHubToken.Write(m_applicationName, deviceConnectionString);
}
else
{
Trace("Could not register ourselves with IoT Hub using owner connection string: " + ownerConnectionString);
}
}
else
{
Trace("IoT Hub owner connection string not found, registration with IoT Hub abandoned.");
}
// try to read connection string from secure store and open IoTHub client
Trace("Attemping to read connection string from secure store with certificate name: " + m_applicationName);
string connectionString = SecureIoTHubToken.Read(m_applicationName);
if (!string.IsNullOrEmpty(connectionString))
{
Trace("Attemping to configure publisher with connection string: " + connectionString);
m_deviceClient = DeviceClient.CreateFromConnectionString(connectionString, Microsoft.Azure.Devices.Client.TransportType.Mqtt);
m_deviceClient.RetryPolicy = RetryPolicyType.Exponential_Backoff_With_Jitter;
m_deviceClient.OpenAsync().Wait();
}
else
{
Trace("Device connection string not found in secure store.");
}
// get a list of persisted endpoint URLs and create a session for each.
try
{
// check if we have an env variable specifying the published nodes path, otherwise use current directory
string publishedNodesFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "publishednodes.json";
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP")))
{
publishedNodesFilePath = Environment.GetEnvironmentVariable("_GW_PNFP");
}
Trace("Attemping to load nodes file from: " + publishedNodesFilePath);
m_nodesLookups = JsonConvert.DeserializeObject<PublishedNodesCollection>(File.ReadAllText(publishedNodesFilePath));
Trace("Loaded " + m_nodesLookups.Count.ToString() + " nodes.");
}
catch (Exception ex)
{
Trace("Nodes file loading failed with: " + ex.Message);
}
// subscribe to preconfigured nodes
Trace("Attemping to subscribe to published nodes...");
if (m_nodesLookups != null)
{
foreach (NodeLookup nodeLookup in m_nodesLookups) foreach (NodeLookup nodeLookup in m_nodesLookups)
{ {
try if (!m_endpointUrls.Contains(nodeLookup.EndPointURL))
{ {
CreateMonitoredItem(nodeLookup); m_endpointUrls.Add(nodeLookup.EndPointURL);
}
catch (Exception ex)
{
Trace("Unexpected error publishing node: " + ex.Message + "\r\nIgnoring node: " + nodeLookup.EndPointURL.AbsoluteUri + ", " + nodeLookup.NodeID.ToString());
} }
} }
// connect to the other servers
Trace("Attemping to connect to servers...");
try
{
List<Task> connectionAttempts = new List<Task>();
foreach (Uri endpointUrl in m_endpointUrls)
{
Trace("Connecting to server: " + endpointUrl);
connectionAttempts.Add(EndpointConnect(endpointUrl));
}
// Wait for all sessions to be connected
Task.WaitAll(connectionAttempts.ToArray());
}
catch (Exception ex)
{
Trace("Exception: " + ex.ToString() + "\r\n" + ex.InnerException != null ? ex.InnerException.ToString() : null);
}
// subscribe to preconfigured nodes
Trace("Attemping to subscribe to published nodes...");
if (m_nodesLookups != null)
{
foreach (NodeLookup nodeLookup in m_nodesLookups)
{
try
{
CreateMonitoredItem(nodeLookup);
}
catch (Exception ex)
{
Trace("Unexpected error publishing node: " + ex.Message + "\r\nIgnoring node: " + nodeLookup.EndPointURL.AbsoluteUri + ", " + nodeLookup.NodeID.ToString());
}
}
}
Trace("Publisher is running. Press enter to quit.");
Console.ReadLine();
foreach (Session session in m_sessions)
{
session.Close();
}
if (m_deviceClient != null)
{
m_deviceClient.CloseAsync().Wait();
}
} }
catch (Exception e)
Console.WriteLine("Publisher is running. Press enter to quit.");
Console.ReadLine();
foreach (Session session in m_sessions)
{ {
session.Close(); Trace(e, "Unhandled exception in Publisher, exiting!");
}
if (m_deviceClient != null)
{
m_deviceClient.CloseAsync().Wait();
} }
} }