WPF: what could happen if 2 instances of my application report to the same log [duplicate] - wpf

I'm using a RollingFileAppender to log some info to a file with a conversionPattern (in the web.config) that looks like this for the header of each log section:
<conversionPattern value="%date - %property{userId} - %property{method}%newline--------------------------------%newline%message%newline%newline"/>
I'd like to log details under this header as bullet points. I'm currently trying to use another RollingFileAppender that logs to the same file with a simple conversionPattern of just a dash, like this:
<conversionPattern value="- %message%newline"/>
But these messages aren't making it into the log file. I'm using Log.Info() for the header and Log.Debug() for the bullet points and filtering each appender on their respective log levels. Is what I'm trying to do possible? Or is there a better way to get header and detail information into a log file from log4net?

Yes you can have two log4net appenders that append (write) to the same log file.
You need to place the following line in each of your Appenders:
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
This will make log4net use a minimal locking model that allows multiple processes to write to the same file.
Here's an example XML that uses two appenders writing to the same log file:
<log4net debug="false">
<appender name="RollingLogFileAppender1" type="log4net.Appender.RollingFileAppender">
<!-- this configures a log for the application messages -->
<file value="TestLog.log" />
<appendToFile value="true" />
<!-- next line uses a minimal locking model that allows multiple processes to write to the same file -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<!-- make the most recent log the highest numbered log -->
<countDirection value="1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date{MM-dd-yyyy HH:mm:ss.ff} [%property{NDC}] %message%newline [Thread: %thread] %c{1} Method:%method(%file{1}, Line:%line) %newline" />
</layout>
<!-- The following two filters insure only log requests of
version '1' use this Appender -->
</appender>
<appender name="RollingLogFileAppender2" type="log4net.Appender.RollingFileAppender">
<file value="TestLog.log" />
<appendToFile value="true" />
<!-- next line uses a minimal locking model that allows multiple processes to write to the same file -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<!-- make the most recent log the highest numbered log -->
<countDirection value="1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date{MM-dd-yyyy HH:mm:ss.ff} [%property{NDC}] [Thread: %thread] %c{1} Method:%method(%file{1}, Line:%line) %newline%message" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender1" />
<appender-ref ref="RollingLogFileAppender2" />
</root>
This can be found in the Apache documentation here:
Apache Log4Net Docs
Just search on this page for 'same file'.
Hope this helps.

You could realize if there is any problem with log4net checking the output window on visual studio. The library log errors there, very useful to detect configuration mistakes.

Related

Configuring Specflow+ Runner for parallel test execution across different Browsers

I am using Specflow+ Runner for my automation testing using Selenium/Appium grid at the backend and want to test my scripts in parallel across multiple Browsers
I have referred to the examples from Specflow examples repository (https://github.com/SpecFlowOSS/SpecFlow.Plus.Examples/tree/master/SeleniumGridWebTest) and using the following Default.srprofile
<?xml version="1.0" encoding="utf-8"?>
<TestProfile xmlns="http://www.specflow.org/schemas/plus/TestProfile/1.5">
<Settings projectName="SpecflowTrial" />
<Execution stopAfterFailures="0" testThreadCount="5" testSchedulingMode="Sequential" retryCount="0" apartmentState="MTA" />
<Environment testThreadIsolation="Process" />
<TestAssemblyPaths>
<TestAssemblyPath>SpecflowTrial.dll</TestAssemblyPath>
</TestAssemblyPaths>
<Report>
<Template name="Report\ReportTemplate.cshtml" />
</Report>
<Targets>
<Target name="Browser_Safari">
<Filter>Browser_Safari</Filter>
<DeploymentTransformationSteps>
<EnvironmentVariable variable="Test_Browser" value="Safari" />
</DeploymentTransformationSteps>
<Environment testThreadIsolation="Process" />
</Target>
<Target name="Browser_Chrome">
<Filter>Browser_Chrome</Filter>
<DeploymentTransformationSteps>
<EnvironmentVariable variable="Test_Browser" value="Chrome" />
</DeploymentTransformationSteps>
<Environment testThreadIsolation="Process" />
</Target>
<Target name="Browser_Firefox">
<Filter>Browser_Firefox</Filter>
<DeploymentTransformationSteps>
<EnvironmentVariable variable="Test_Browser" value="Firefox" />
</DeploymentTransformationSteps>
<Environment testThreadIsolation="Process" />
</Target>
</Targets>
<TestThreads>
<TestThread id="0">
<TestAffinity>testpath:Target:Browser_Safari</TestAffinity>
</TestThread>
<TestThread id="1">
<TestAffinity>testpath:Target:Browser_Chrome</TestAffinity>
</TestThread>
<TestThread id="2">
<TestAffinity>testpath:Target:Browser_Firefox</TestAffinity>
</TestThread>
</TestThreads>
</TestProfile>
where the filters are applied to tags on the scenarios
My problem is that when running all tests in parallel, sometimes the tests are triggered across different browsers and sometimes it is triggered for the same Browsers, in this case, all run on either Chrome, Firefox or Safari.
What is the correct configuration that should be used to trigger tests in parallel across different browsers?
Update:
The above question was resolved bumping the SpecRun to version 3.6.2

Failure obtaining db row lock

My application has been working fine for the last 2 months. Last week number of users doubled so we started seeing this error in the log:
"Failure obtaining db row lock: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."
The issue resolves it self when the number of user activity goes down.
The locks are happening because of these 2 queries:
SELECT * FROM QRTZ_LOCKS WITH (UPDLOCK,ROWLOCK) WHERE SCHED_NAME =
'QuartzScheduler' AND LOCK_NAME = #lockName
(#lockName nvarchar(14))SELECT * FROM QRTZ_LOCKS WITH
(UPDLOCK,ROWLOCK) WHERE SCHED_NAME = 'QuartzScheduler' AND LOCK_NAME =
#lockName
Things I tried:
I tried to restart the services but that didn't help.
I added an indexes to the quarts_trigger table but it didn't help.
I changed the database Cost Threshold for Parallelism to 50 and Max
Degree of Parallelism to 4 and that didn't help.
System:
We are using Quartz 2.3.1
We have 2 quartz services in 2 different servers accessing one quartz database.
Triggers are being created from 3 different web applications.
Quartz Configuration:
<add key="quartz.scheduler.instanceName" value="QuartzScheduler" />
<add key="quartz.scheduler.instanceId" value="AUTO" />
<add key="quartz.scheduler.jobFactory.type" value="Quartz.Server.Bootstrap.QuartzUnityJobFactory, Quartz.Server"/>
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="30" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.useProperties" value="false" />
<add key="quartz.jobStore.dataSource" value="default" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.clustered" value="true" />
<add key="quartz.jobStore.misfireThreshold" value="176400000" /> <!-- 49 hours -->
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz" />
<add key="quartz.dataSource.default.connectionString" value="*****" />
<add key="quartz.dataSource.default.provider" value="SqlServer-20" />
<add key="quartz.jobStore.acquireTriggersWithinLock" value="true" />
<add key="quartz.scheduler.batchTriggerAcquisitionMaxCount" value="10" />
Any ides?

log4net log file not being written when the app is deployed

I have a WPF app that uses log4net. When I run it in Visual Studio, the log file is created in the Debug or Release folder as expected.
However, when I create an installer and run the installed app, the log file is not created. I added the following lines to the code...
string logFilePath = ((Hierarchy)LogManager.GetRepository())
.Root.Appenders.OfType<FileAppender>()
.FirstOrDefault()?.File;
using (StreamWriter sw = new StreamWriter(#"d:\log.log")) {
sw.WriteLine("Log file: " + logFilePath);
}
...to enable me to check that the log file was being written in the location I expected. It showed me that the log file was supposed to be written to C:\Program Files (x86)\Physio Diary\PhysioDiaryClient.log which is what I expected.
However, the file doesn't exist. Any idea why?
Here is the top of the App.config file...
<?xml version="1.0"
encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender"
type="log4net.Appender.RollingFileAppender">
<param name="File"
value="PhysioDiaryClient.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-7level %logger - %message%newline%exception" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
The bottom of the file looks like this...
<startup>
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
The bits in between are all to do with the WCF services that the app uses.
Anyone any ideas?
Edit: As a test, I tried hard-coding the log file path in App.config to my D: drive (so it's hard-coded, and no question of a permissions issue), but the file still wasn't created.
Thanks to #dymanoid for pointing me in the right direction. The log4net docs are a bit weak in this area, but I found this answer that pointed out that you can use normal environment variables in the config file.
With the aid of this list of environment variables, I ended up with the following...
<param name="File"
value="${LOCALAPPDATA}\Physio Diary\PhysioDiaryClient.log" />
This correctly write the file to C:\Users\MyUsername\AppData\Local\Physio Diary\PhysioDiaryClient.log
Hope this helps someone.

Can't insert into SQL Server table with log4net AdoNetAppender

I am trying to understand how log4net works so I've added this to my app.config (I should add that Console Appender and FileAppender work perfectly, I only have trouble with the AdoNetAppender).
How can I debug this, to see if at least the connection to db succeeds?
The problem is the INSERT statement isn't executed.
I should add the
Data Source=MyWorkgroup\SQLEXPRESS;Initial Catalog=MyNewDatabase;User ID=juan;password=juan,
works perfectly when I try to connect to SQL Server manually, so not sure if that's the problem.
Also, the ConnectionType was taken from the official site:
https://logging.apache.org/log4net/log4net-1.2.11/release/sdk/log4net.Appender.AdoNetAppender.ConnectionType.html
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.log4netConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<appender name="AdoNetAppender"
type="log4net.Appender.AdoNetAppender">
<bufferSize value="10" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="Data Source=MyWorkgroup\SQLEXPRESS;Initial Catalog=MyNewDatabase;User ID=juan;Password=juan;Pooling=False" />
<commandText value="INSERT INTO Logs([logDate],[logThread],[logMessage]) VALUES(getdate(),'1','1')" />
<commandType value="Text" />
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="AdoNetAppender"/>
</root>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Later edit (after using the debug method recommended by David):
haacked.com is indeed extremely interesting, great tip! However, it seems that it's describing what I'm instructing log4net to log, but not the result of those actions(?), if I'm reading this well (no failed/or succeeded?)
e.g.
log4net: Setting Property [ConnectionType] to String value
[System.Data.SqlClien t.SqlConnection, System.Data,
Version=1.0.3300.0, Culture=neutral, PublicKeyToke n=b77a5c561934e089]
log4net: Setting Property [ConnectionString] to String value [Data
Source=MyWorkgroup\SQLEXPRESS; Initial
Catalog=MyNewDatabase;
User ID=juan; Password=juan;
Pooling=False] log4net: Setting Property [CommandText] to String value [INSERT INTO Logs([logDate],[logThread],[logMessage]) VALUES(getdate(),'1','1')] log4net:
Setting Property [CommandType] to CommandType value [Text] log4net:
Created Appender [AdoNetAppender] log4net: Adding appender named
[AdoNetAppender] to logger [root]. log4net: Hierarchy Threshold []
Piece of code that helped me obtain this info (in case the site should become unavailable) is:
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\temp\log4netdiagn.txt" />
</listeners>
</trace>
</system.diagnostics>

Using Log4Net and the AdoNetAppender to write an XMLLayout parameter to a DbType XML field

Pretty straightforward question.
I have a table on a SQL Server Database that has an field with a DbType of XML.
I would like to write to that field using the format of Log4Net's XML layout WITHOUT writing a custom appender; using the in-the-box AdoNetAppender.
Below is my current code, however, when it attempts to log, it will insert a record, but the "Exception" field will be blank.
(I've simplified the code for the purpose of this question; it used to write to many other fields using the pattern layout. I've confirmed that the Appender does work and that log4net is configured properly, I'm just trying to log to a dbtype of XML using log4net's included XMLLayout.)
<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<ConnectionStringName value="CONNECTIONSTRING"/>
<commandText value="dbo.TestLog_Insert #Exception = #Exception" />
<parameter>
<parameterName value="#Exception"/>
<dbType value="XML"/>
<size value="4000"/>
<layout type="log4net.Layout.XMLLayout" value="%exception" />
</parameter>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO"/>
<acceptOnMatch value="true"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
</appender>

Resources