I use nlog dll to write to database - oracle with entity frameWork in the line :
logger.Log(logLevel, "try");
I get in the logs of NLog the following error:
Warn DatabaseTarget: Parameter: 'TIME_STAMP' - Failed to assign DbType=OracleDbType.Date
Error DatabaseTarget(Name=WS_TRACE): Error when writing to database. Exception: System.Data.OracleClient.OracleException (0x80131938): ORA-01843: Invalid month
the code is:
SetPropGDC(LogEntity);
NLog.LogLevel logLevel = SetLogLevel(Level.Debug);
logger.Log(logLevel, "try");
ClearGDC();
private void SetPropGDC(LogEntity LogEntity)
{
GlobalDiagnosticsContext.Set(processId, LogEntity.PROCESS_ID.ToString());
GlobalDiagnosticsContext.Set("TIME_STAMP", DateTime.Now);
GlobalDiagnosticsContext.Set(customerId, LogEntity.CUSTOMER_ID.ToString());
}
<targets>
<target name="TRACEDatabase" type="DataBase" keepConnection="false"
dbProvider="Oracle.ManagedDataAccess.Client" connectionString="${gdc:connectionString}"
commandText="insert into TLOG_SITE_GENERAL_TRACE( PROCESS_ID,TIME_STAMP,CUSTOMER_ID)
values(:PROCESS_ID,:TIME_STAMP,:CUSTOMER_ID)">
<parameter name="PROCESS_ID" layout="${gdc:PROCESS_ID}" />
<parameter name="TIME_STAMP" layout="${gdc:TIME_STAMP}" dbType="OracleDbType.Date" />
<parameter name="CUSTOMER_ID" layout="${gdc:CUSTOMER_ID}" />
</target>
</targets>
I tried in the Web.config to change the line:
<parameter name="TIME_STAMP" layout="${gdc:TIME_STAMP}" dbType="OracleDbType.Date" />
to:
<parameter name="TIME_STAMP" layout="${longDate}" dbType="OracleDbType.Date" />
and I got the same error
First of all, it's highly recommend to use the built in layout renderers.
For example, ${longdate}, but also ${processid}. Those are optimized and easier to use.
You can find all of them here
Be aware is that using global context (GDC), could be dangerous in multi threaded programs. Also in single threaded you could "leak" some context.
But I guess the real issue here is that your NLog is out to date. DbType support is added in NLog 4.6.
So first update NLog (using Nuget is highly recommend). I use here NLog 4.6.3+, but would recommend to update to NLog 4.7
Then for the code I would recommend to do this:
logger.WithProperty("CustomerId", LogEntity.CUSTOMER_ID).Log(loglevel, "Message");
and configure like this:
<targets>
<target name="TRACEDatabase" type="DataBase" keepConnection="false"
dbProvider="Oracle.ManagedDataAccess.Client" connectionString="${gdc:connectionString}"
commandText="insert into TLOG_SITE_GENERAL_TRACE( PROCESS_ID,TIME_STAMP,CUSTOMER_ID)
values(:PROCESS_ID,:TIME_STAMP,:CUSTOMER_ID)">
<parameter name="PROCESS_ID" layout="${processid}" dbType="Int32" />
<parameter name="TIME_STAMP" layout="${longdate}" dbType="Date" />
<parameter name="CUSTOMER_ID" layout="${event-properties:CUSTOMER_ID}" dbType="Int32" />
</target>
</targets>
See also ${event-properties}
There is no need for using a specific OracleDbType, so therefor I choose to just use "Date" (which is DbType.Date, see DbType
I found the solution!
I changed the dbType parameter from:
<parameter name="TIME_STAMP" layout="${gdc:TIME_STAMP}" dbType="OracleDbType.Date" />
To:
<parameter name="TIME_STAMP" layout="${gdc:TIME_STAMP}" dbType="DateTime" />
and it works!
Related
I'm looking at implementing a runsettings file for automated testing. Thing is, my variables are complex objects, and all I can find in the documentation about runsettings has simple key/value options, like so.
<TestRunParameters>
<Parameter name="webAppUrl" value="http://localhost" />
<Parameter name="docsUrl" value="https://learn.microsoft.com" />
</TestRunParameters>
I'm wondering if it's possible to specify a complex object like you might specify below (especially since TextContext.Properties returns an object, so I assume it's polymorphic in some sense?) and cast it to a given defined class
<TestRunParameters>
<Parameter name="AdminUser" UserID="Admin" Password="P#55w0rd!" />
<Parameter name="User" UserID="User" Password="P#55w0rd!" />
</TestRunParameters>
I realize I can do the below and manually create my object instances, but I'd really really like to avoid it if at all possible
<TestRunParameters>
<Parameter name="AdminUserID" value="Admin"/>
<Parameter name="AdminUserPW" value="P#55w0rd!" />
<Parameter name="UserID" value="User"/>
<Parameter name="UserPW" value="P#55w0rd!" />
</TestRunParameters>
I have setup NLog on my project that will save the logging to my audit database (separate from the default database). However, it is failing to write to the database. I have a console logger target as well and that is logging as expected. No errors are shown or given. It merely fails to write to the database.
I have tried various methods provided from google, but none seemed to have worked. I have also tried using NLogBuilder to configure the config for that specific controller but still, it doesn't write to the database
nlog.config file:
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
</configSections>
<nlog internalLogLevel="Trace">
<targets>
<target name="ConsoleLogger" type="Console"
layout="${longdate}|${level:uppercase=true}|${logger}|${message}"/>
<target name="DatabaseLog" type="Database">
<commandtext>
INSERT INTO Logs
(LogDate, LogLevel, Message, Exception)
VALUES
(#log_date, #log_level, #message, #exception)
</commandtext>
<parameter name="#log_date"
layout="${log_date}"
dbType="DateTime"/>
<parameter name="#thread"
layout="${thread}"
dbType="String"
size="255"/>
<parameter name="#log_level"
layout="${log_level}"
dbType="String"
size="20" />
<parameter name="#logger"
layout="${logger}"
dbType="String"
size="250" />
<parameter name="#message"
layout="${message}"
dbType="String"
size="4000" />
<parameter name="#exception"
layout="${exception}"
dbType="String"
size="4000" />
<dbProvider>MySql.Data.MySqlClient.MySqlConnection, MySql.Data</dbProvider>
<connectionString>User Id=username;Password=password;Host=localhost;Database=audit_database;TreatTinyAsBoolean=false</connectionString>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" maxlevel="Fatal" writeTo="ConsoleLogger,DatabaseLog" />
</rules>
</nlog>
Controller method:
public static Logger _logger = LogManager.GetCurrentClassLogger(typeof(ActionerController));
_logger.Info("text");
Main.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddNLog();
}).ConfigureAppConfiguration((hostingContext, config) =>
{
config
.AddJsonFile($"environment-mount/appsettings.json", optional: true)
.AddEnvironmentVariables();
}).ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
For MySQL, make sure you have installed the MySql.Data package.
There are also some mistakes in your config and code:
${log_date}, ${log_level} and ${thread} don't exist. I guess you mean ${date}, ${level} and ${threadid}. See all options here.
LogManager.GetCurrentClassLogger with an argument expects a logger type - so inherits from NLog.Logger. I think you are looking for LogManager.GetCurrentClassLogger() or LogManager.GetLogger(typeof(ActionerController).FullName). See API docs
Of course there could be other errors, e.g. a wrong query, mistyped colum names or wrong column types. NLog could of course tell you the problem:
Or enable exceptions. In your config <nlog throwExceptions=true >
Or enable the internal log: <nlog internalLogFile="c:\log.txt" internalLogLevel="Warn">. Read more here
I'm trying to use NLog to log to an Oracle database, already created the table but when I try to log something I get the exception:
ORA-00928: missing SELECT keyword
My NLog.config file is:
<?xml version="1.0" ?>
<nlog autoReload="true" throwExceptions="true" internalLogFile="${basedir}/App_Data/nlog.txt" internalLogLevel="Debug"
internalLogToConsole="true">
<targets>
<!--Useful for debugging-->
<target name="filelog" type="File" fileName="C:/App_Data/Site.log"
layout="${date}: ${message}" />
<target name="databaselog" type="Database">
<dbProvider>Oracle.DataAccess.Client</dbProvider>
<!-- database connection parameters -->
<!-- alternatively you could provide a single 'connectionstring' parameter -->
<connectionString>DATA SOURCE=database;PERSIST SECURITY INFO=True;USER ID=user;Password=password;Validate Connection=true</connectionString>
<commandText>
insert into RS_LOGTABLE ([log_user],[log_level],[log_date],[log_message]) values(#log_user,#log_level,#log_date,#log_message);
</commandText>
<parameter name="#log_user" layout="${message}"/>
<parameter name="#log_level" layout="${message}"/>
<parameter name="#log_date" layout="${date}"/>
<parameter name="#log_message" layout="${message}"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="filelog" />
<logger name="*" minlevel="Trace" writeTo="databaselog" />
</rules>
</nlog>
And the exception occurs when I do this:
logger = LogManager.GetCurrentClassLogger();
logger.Debug("Teste logger");
I already tried to do the insert without the brackets and get another exception:
**ORA-00936: missing expression**
I guess it's bit late for you, but I hope my solution will be helpful for others.
I changed characters # for colons at commandText and at parameter tags I removed it completely. I don't use brackets and it started to work.
It should be correct this way:
<commandText>
insert into RS_LOGTABLE (log_user,log_level,log_date,log_message) values(:log_user,:log_level,:log_date,:log_message);
</commandText>
<parameter name="log_user" layout="${message}"/>
<parameter name="log_level" layout="${message}"/>
<parameter name="log_date" layout="${date}"/>
<parameter name="log_message" layout="${message}"/>
I tested it with dbProvider Oracle.DataAccess.Client.
Warning for others:
I had a variable named with reserved word and it throws another exception. More details are here PHP ORA-01745: invalid host/bind variable name Warning
I'm testing a very simple script to try and run my ant build file from CruiseControl.NET. I followed the steps I found on the net of how to do this but i keep getting nAnt task failed in CruiseControl without any explanation and yet when i run the NAnt build script separately, it runs fine.
Can anybody take a look at my build script, the Ccnet.config file and the output in the log and point me in the right direction?
My XmLib.build NAnt file
<?xml version="1.0"?>
<project default="start">
<property name="code.directory" value="C:\SHS" />
<property name="server.code.directory" value="${code.directory}\XmLib" />
<property name="server.code.project" value="${server.code.directory}\XmLib.sln" />
<target name="start">
<echo message="Building XmLib Component " />
</target>
</project>
My output when I ran my build file using Nant.exe via command line.
Buildfile: file:///C:/SHS/Build Scripts/XmLib.build
Target framework: Microsoft .NET Framework 4.0
Target(s) specified: start
start:
[echo] Building XmLib Component
BUILD SUCCEEDED
Total time: 0.4 seconds.
My CruiseControl.NET config file
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<project name="XmLib">
<tasks>
<nant>
<executable>C:\Program Files (x86)\NAnt\bin\nant.exe</executable>
<baseDirectory>C:\SHS\Build Scripts</baseDirectory>
<buildFile>XmLib.build</buildFile>
<logger>NAnt.Core.XmlLogger</logger>
<targetList>
<target>start</target>
</targetList>
<buildTimeoutSeconds>80</buildTimeoutSeconds>
</nant>
</tasks>
<publishers>
<xmllogger logDir="C:\tmp" />
</publishers>
</project>
</cruisecontrol>
The error I get when I try to run this via CruiseControl.NET using its dashboard.
<cruisecontrol project="XmLib">
<request source="BUILDHPSMV" buildCondition="ForceBuild">Administrator triggered a build (ForceBuild) from BUILDHPSMV</request>
<parameters>
<parameter name="$CCNetArtifactDirectory" value="C:\Program Files (x86)\CruiseControl.NET\server\XmLib\Artifacts" />
<parameter name="$CCNetBuildCondition" value="ForceBuild" />
<parameter name="$CCNetBuildDate" value="2013-01-16" />
<parameter name="$CCNetBuildId" value="a7fb196a3193468e8d8505f7db7641d5" />
<parameter name="$CCNetBuildTime" value="17:06:44" />
<parameter name="$CCNetFailureTasks" value="System.Collections.ArrayList" />
<parameter name="$CCNetFailureUsers" value="System.Collections.ArrayList" />
<parameter name="$CCNetIntegrationStatus" value="Unknown" />
<parameter name="$CCNetLabel" value="1" />
<parameter name="$CCNetLastIntegrationStatus" value="Failure" />
<parameter name="$CCNetListenerFile" value="C:\Program Files(x86)\CruiseControl.NET\server\XmLib\Artifacts\XmLib_ListenFile.xml" />
<parameter name="$CCNetModifyingUsers" value="System.Collections.ArrayList" />
<parameter name="$CCNetNumericLabel" value="1" />
<parameter name="$CCNetProject" value="XmLib" />
<parameter name="$CCNetProjectUrl" value="http://BUILDHPSMV/ccnet" />
<parameter name="$CCNetRequestSource" value="BUILDHPSMV" />
<parameter name="$CCNetUser" value="Administrator" />
<parameter name="$CCNetWorkingDirectory" value="C:\Program Files(x86)\CruiseControl.NET\server\XmLib\WorkingDirectory" />
</parameters>
<modifications />
<integrationProperties>
<CCNetArtifactDirectory>C:\Program Files(x86)\CruiseControl.NET\server\XmLib\Artifacts</CCNetArtifactDirectory>
<CCNetBuildCondition>ForceBuild</CCNetBuildCondition>
<CCNetBuildDate>2013-01-16</CCNetBuildDate>
<CCNetBuildTime>17:06:44</CCNetBuildTime>
<CCNetFailureUsers />
<CCNetFailureTasks>
<task>NAntTask</task>
</CCNetFailureTasks>
<CCNetIntegrationStatus>Failure</CCNetIntegrationStatus>
<CCNetLabel>1</CCNetLabel>
<CCNetLastIntegrationStatus>Failure</CCNetLastIntegrationStatus>
<CCNetListenerFile>C:\Program Files(x86)\CruiseControl.NET\server\XmLib\Artifacts\XmLib_ListenFile.xml</CCNetListenerFile>
<CCNetModifyingUsers />
<CCNetNumericLabel>1</CCNetNumericLabel>
<CCNetProject>XmLib</CCNetProject>
<CCNetProjectUrl>http://BUILDHPSMV/ccnet</CCNetProjectUrl>
<CCNetRequestSource>BUILDHPSMV</CCNetRequestSource>
<CCNetWorkingDirectory>C:\Program Files(x86)\CruiseControl.NET\server\XmLib\WorkingDirectory</CCNetWorkingDirectory>
<CCNetUser>Administrator</CCNetUser>
<CCNetBuildId>a7fb196a3193468e8d8505f7db7641d5</CCNetBuildId>
<LastIntegrationStatus>Failure</LastIntegrationStatus>
<LastSuccessfulIntegrationLabel>UNKNOWN</LastSuccessfulIntegrationLabel>
<LastModificationDate>1/15/2013 5:06:44 PM</LastModificationDate>
</integrationProperties>
<build date="2013-01-16 17:06:44" buildtime="00:00:00" error="true"buildcondition="ForceBuild"></build>
</cruisecontrol>
Only a guess but I suspect unquoted paths as cause of the failure. Try "C:\Program Files (x86)\NAnt\bin\nant.exe" resp. "C:\SHS\Build Scripts".
I am having a bit of a problem using a stored procedure instead of a SQL INSERT statement when using NLog in a C# web application. The connection string "Logger" is correctly configured in Web.config and works properly when replacing the commandText with a SQL statement. I would appreciate a hint in the right direction. In this example the stored procedure is under the "Logs" schema and it is called "LogError".
<targets>
<target xsi:type="Database"
name="dberrorlog"
connectionStringName="Logger"
keepConnection="true"
commandText="[Logs].[LogError]" >
<parameter name="#ProgName" layout="MyAppName"/>
<parameter name="#CompName" layout="${machinename}"/>
<parameter name="#LogLevel" layout="${level}"/>
<parameter name="#UserName" layout="${identity}"/>
<parameter name="#Error" layout="${exception:format=Message}"/>
<parameter name="#SourceObj" layout="${exception:format=Method}"/>
<parameter name="#StackTrace" layout="${exception:format=StackTrace}"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Error" writeTo="dberrorlog" />
</rules>
From this NLog forum post, try using the text to execute the stored procedure:
commandtext="exec AddActivityLog
#ApplicationName,
#ApplicationTime,
#Severity,
#Logger,
#SaxoID,
#EventID,
#Message,
#URL,
#URLReferrer,
#RemoteAddress,
#Callsite,
#CurrentUICulture,
#ThreadIdentity,
#WindowsIdentity,
#MachineName,
#ProcessID,
#ThreadID,
#ThreadName,
#Stacktrace,
#Exception,
#Cookie,
#FormVariables,
#QueryString,
#HTTPUserAgent"
Side note: Claus Rathje's answer wouldn't render in my browser, so I had to look a the page source to see the configuration he posted.
Note that while #JeffOgata's solution works, it's probably not the way you want to go about solving the problem.
You can do something like this instead:
commandText="AddActivityLog"
commandType="StoredProcedure"
That way you don't have to worry about properly formatting an EXEC query.