Enterprise library logging : how to print method name and line number with each log entry. - enterprise-library

Is there a predifined way of doing this or do we need to define our own custom formatter?

You dont say which version of EntLib you are using but given the date of your post I will assume EntLib 5.0.
The part of the format string you would be interested in is:
Extended Properties: {dictionary({key} - {value}{newline})}
This is a part of the total "default" formatter template found in your config file as below:
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="Timestamp: {timestamp}{newline}
Message: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}" name="Text Formatter" />
</formatters>
So you can see Extended Properties is a dictionary which will be automatically iterated by the Logger when creating the log entry. It's purpose it to provide a quick and dirty way to dump extra output your app may provide. A more complete way to this would be to write a custom formatter that specifically has tokens for each of the objects you would have otherwise added to Extended Properties.
To get properties into this collection just use the appropriate overload of the
LogWriter.Write(..)
method when making an entry. A few of them have an
IDictionary(key, string) properties
parameter that you can use to supply these values.
As for line number and method name these can just be inserted into the Dictionary you provide above. To get their values you can just:
private void FillExtraLogInfo(IDictionary<string, object> info)
{
StackFrame stackFrame = new StackFrame(1, true);
info.Add("Method Name", stackFrame.GetMethod().ToString());
info.Add("Line Number" stackFrame.GetFileLineNumber());
}

You can get the method name by configuring your TextFormatter in the config file. I've included the whole formatter to give you some context but the key thing to look for is the {property(MethodName)} in the template attribute. I'm not sure how to get the line number.
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
template="Timestamp: {timestamp}{newline}
Title: {title}{newline}
Message: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}
Type: {property(TypeName)}{newline}
Method: {property(MethodName)}{newline}
Parameters: {dictionary({key} : {value};)}{newline}
Return Value: {property(ReturnValue)}{newline}
Call Time: {property(CallTime)}{newline}"
name="Detailed Text Formatter" />
</formatters>
</loggingConfiguration>
The MSDN article on Configuring Formatters mentions these special tokens but unfortunately doesn't explain how to use them very well.

Related

Could not create content describer for com.example.cstfile. Content type has been disabled

I'm trying to add a content type for my XML files with a custom file extension(CST) and I get the following error -
Could not create content describer for com.example.cstfile. Content type has been disabled.
Here's my plugin.xml file -
<extension point="org.eclipse.core.contenttype.contentTypes">
<content-type
base-type="org.eclipse.core.runtime.xml"
file-extensions="cst,xml"
id="cstfile"
name="CST File"
priority="normal">
<describer class="org.eclipse.core.runtime.content.XMLRootElementContentDescriber2"
plugin="org.eclipse.core.runtime">
<parameter name="elementNames" value="CSTFile"/>
</describer>
</content-type>
<file-association
content-type="org.eclipse.core.runtime.xml"
file-extensions="cst">
</file-association>
</extension>
I'm trying to figure out the reason by debugging org.eclipse.core.internal.content.ContentTypeCatalog but have not found any reasons so far, any help is appreciated.
It looks like it comes from calls to ContentTypes.invalidateDescriber - the content describer has thrown an exception.
Looking at XMLRootElementContentDescriber2 it will throw an exception if it gets a javax.xml.parsers.ParserConfigurationException exception when try to parse the XML.
There should be more information in the .log file in the .metadata directory of the workspace.

Why YAML Schema (from JSON Schema) is returning $ref x in schema can not be resolved?

I have this schema file in ./types/index.yaml:
$schema: "https://json-schema.org/draft/2020-12/schema"
name: Types in YAML
definitions:
flow:
type: object
properties:
slug:
type: string
flow_list:
type: 'array'
items:
$ref: "#/definitions/flow"
And I have this "instance" YAML file, in contents/en.yaml:
# yaml-language-server: $schema=../types/index.yaml#definitions/flow_list
-
slug: '123'
I would expect it to allow me to create a list of objects with the slug property on it (to get started), but instead I am getting something like this (with the ...... filled in with the full absolute OS path):
$ref 'definitions/flow_list' in 'file:///...../types/index.yaml' can not be resolved.
I am using the RedHat VSCode YAML extension. Any ideas on how to get it so I can write the array of "flows" here?
Restarting VSCode a few times seemed to fix it.

How to ignore special characters in File Transformation Task of Azure DevOps Pipeline

I am having xyz.config file like below. I have created xyx.Release.config file to use in File Transformation task.
<formatters>
<add template="Timestamp: {timestamp}
Message: {message}
name="Reduced Text Formatter" />
</formatters>
After the File Transformation task in pipeline it transformed as below. The special characters are replaced after the execution of File Transformation task.
<formatters>
<add template="Timestamp: {timestamp}
Message: {message}
-
</formatters>
Anyone please let me know how to ignore special character transformation as part of File Transformation task.
Thanks in advance.
Mohan
As far as I know, the File transform task doesn't support to ignore special character transformation.
The file transfrom task will use the built-in method to do the file transform option. It doesn't support to use custom method to do the option.
Here is the doc about the built-in method: Web.config Transformation Syntax for Web Project Deployment Using Visual Studio
It supports overall replacement of strings, but currently does not support replacing only the part of value in the string and ignoring others.
For a workaround, you can use the replace method then just change the part of value in the string to keep the format of the string.
For example: xyx.Release.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<formatters>
<add template="Timestamp: test1
Message: test2
" name="Reduced Text Formatter" xdt:Transform="Replace" xdt:Locator="Match(template)" />
</formatters>
</configuration>

Querying svc log file with logParser

I have generated a xml trace for my program using the Enterprise Library TraceManager. It works great. Using the Microsoft Service Trace Viewer, I can see a separate trace per call.
I would love to query the file so I found Microsoft Logparser and was hopeful I could use that. Unfortunately, I cannot figure out the expected input format. Input of XML returns a error of more than one root node found for the document. None of the other format parse the correct number of line.
Has anyone had any success querying a SVCLog File
TraceManager traceManager
traceManager = EnterpriseLibraryContainer.Current.GetInstance<TraceManager>();
TraceLogEntry traceEntry = new TraceLogEntry();
using (this.traceManager.StartTrace("Tracing")){
traceEntry.Title = "Message";
traceEntry.Priority = Priority;
this.traceManager.LogWriter.Write(traceEntry);
}
The Tracing Category is hooked up to a XML trace listener:
< loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
< listeners>
< add name="XML Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.XmlTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.XmlTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
fileName="c:\A2ISOtrace.svclog" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId" />
< /listeners>
< categorySources>
< add switchValue="All" name="Tracing">
< listeners>
< add name="XML Trace Listener" />
< /listeners>
< /add>
< /categorySources>
Log produces a number of rows like:
< E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent"><System <EventID>1</EventID><Type>3</Type>. . . .
Since your SVCLog file is missing a root element you could embed it into a basic Xml document.
The Xml document
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE Root SYSTEM "Test.dtd">
<Root>
&svclog;
</Root>
The DTD document
<!ENTITY svclog SYSTEM "SVCLog.xml">
where you declare the ENTITY svclog importing your SVCLog file.
Now you should be able to parse the Xml input.

Subsonic Access To App.Config Connection Strings From Referenced DLL in Powershell Script

I've got a DLL that contains Subsonic-generated and augmented code to access a data model. Actually, it is a merged DLL of that original assembly, Subsonic itself and a few other referenced DLL's into a single assembly, called "PowershellDataAccess.dll. However, it should be noted that I've also tried this referencing each assembly individually in the script as well and that doesn't work either.
I am then attempting to use the objects and methods in that assembly. In this case, I'm accessing a class that uses Subsonic to load a bunch of records and creates a Lucene index from those records.
The problem I'm running into is that the call into the Subsonic method to retrieve data from the database says it can't find the connection string. I'm pointing the AppDomain at the appropriate config file which does contain that connection string, by name.
Here's the script.
$ScriptDir = Get-Location
[System.IO.Directory]::SetCurrentDirectory($ScriptDir)
[Reflection.Assembly]::LoadFrom("PowershellDataAccess.dll")
[System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "$ScriptDir\App.config")
$indexer = New-Object LuceneIndexingEngine.LuceneIndexGenerator
$indexer.GeneratePageTemplateIndex("PageTemplateIndex");
I went digging into Subsonic itself and the following line in Subsonic is what's looking for the connection string and throwing the exception:
ConfigurationManager.ConnectionStrings[connectionStringName]
So, out of curiosity, I created an assembly with a single class that has a single property that just runs that one line to retrieve the connection string name.
I created a ps1 that called that assembly and hit that property. That prototype can find the connection string just fine.
Anyone have any idea why Subsonic's portion can't seem to see the connection strings?
Did you add the System.Configuration assembly to your PowerShell session? The following works for me:
PS> gc .\app.config
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings>
<clear />
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
</configuration>
PS> [appdomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "$home\app.config")
PS> Add-Type -AssemblyName System.Configuration
PS> [Configuration.ConfigurationManager]::ConnectionStrings['Name']
Name : Name
ConnectionString : Valid Connection String;
...