Overriding/merging standard programmatic configuration with config file section - configuration

We have a standard set of conventions that we follow for logging from our various applications, and it is sensible to package this configuration as by-code configuration and include in a common assembly.
Occasionally, however, we need to override this config to more efficiently debug production issues. This is more easily accomplished by letting a developer or administrator add an NLog config section, which can be read in and override or add to configuration done programmatically.
Can this be done out of the box with NLog?

I know this isn't by-code (I'm not sure how to do it), but you can use <include> with XML config to override things like variables. Here's a sample that uses Web.config that overrides the "standard" NLog.config for other projects:
Web.config:
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
</configSections>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<include file="${basedir}\bin\NLog.config" />
<variable name="fruit" value="Apples" />
</nlog>
</configuration>
NLog.config (that gets copied to bin):
<?xml version="1.0"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<!-- Output Window -->
<target name="debug" xsi:type="Debugger" layout="${fruit}|${level:uppercase=true}|${logger}|${message}"></target>
</targets>
<rules>
<logger name="*" writeTo="debug" />
</rules>
</nlog>

Related

Limiting Checkstyle to certain packages

I have a project with several hundred packages. It's mostly generated code from a conversion from COBOL to inline java so the vast majority of it (~11,000 files) is something I do not want to run checkstyle on. I do have a couple packages in the project that are "real" java that I have added to replace utilities that could not be generated by the code conversion and I do want to run checkstyle on those.
I'm having trouble getting the suppression to work properly.
This is the relevant fragment from the checkstyle.xml:
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the Google coding conventions from Google Java Style
that can be found at https://google.github.io/styleguide/javaguide.html.
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
To completely disable a check, just comment it out or delete it from the file.
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
-->
<module name = "Checker">
<property name="charset" value="UTF-8"/>
<property name="severity" value="warning"/>
<property name="fileExtensions" value="java, properties, xml"/>
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="SuppressionFilter">
<property name="file" value="${config_loc}/checkstyleSuppress.xml"/>
<property name="optional" value="false"/>
</module>
<module name="TreeWalker">
<module name="OuterTypeFilename"/>
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
<property name="format"
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message"
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
</module>
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowEscapesForControlCharacters" value="true"/>
<propert ...
I'm confident that the checkstyleSuppress.xml file is getting read because checkstyle will error out if I add a character to the file name to make it wrong.
The content of checkstyleSuppress.xml is as follows:
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<suppress files="[/\\].+" checks=".*"/>
<suppress checks=".*" files="app[\\/]dbio[\\/].java"/>
<suppress checks=".*" files="app[\\/]dbio[\\/]internal[\\/].java"/>
<suppress checks=".*" files="app[\\/]f17*[\\/].java"/>
<suppress checks=".*" files="app[\\/]f17*[\\/]internal[\\/].java"/>
</suppressions>
What I'm trying to do is suppress all checks for anything in the app.dbio and app.f17* packages. To see if my rules are running I added the first line in the file which I thought would suppress all checks on all files.
None of these filters are suppressing anything. Checkstyle checks all files in all packages (and reports over 400,000 violations, which is a bit too many to wade through for the ones I care about! lol)
Most projects are ground up, so I have previously used checkstyle with no suppression. This is my first attempt to limit the scope of the code review and it's not going as I had hoped. I'm not sure where my issue lies here.
Any suggestions are much appreciated.
I think BeforeExecutionExclusionFileFilter is the thing you are looking for. You can provide regexp(s) which matches packages you want to exclude, they will not be checked.

NoClassDefFoundError when checkstyle is running

I have written a new checkstyle check as a filescanner. I modeled my junits after the code I found in the checkstyle code. The junits run just fine and everything looks good.
But then, I add the check to my project.
<module name="TreeWalker">
<property name="tabWidth" value="4" />
<module name="com.onuspride.codetools.checkstyles.DuplicateClassNames"/>
</module>
and my ant task
<taskdef resource="checkstyletask.properties">
<classpath refid="classpath" />
</taskdef>
<property name="checkstyle.suppressions.file" value="checkstyle/suppressions.xml" />
<property name="translation.severity" value="error" />
<target name="checkStyle" description="TestTask to evaluate the checkstyle system.">
<checkstyle config="checkstyle/checkstyle_checks.xml">
<fileset dir="${msg.src}" includes="**/*.java" />
<formatter type="plain" />
<formatter type="xml" toFile="${msg.build.jar}/checkstyle_errors.xml" />
<classpath refid="classpath" />
</checkstyle>
</target>
the duplicateclassnames class calls several classes in the same jar. For some reason, when ant runs it, ant finds the check class, but can't find the supporting classes, when they are all in the same jar file. here's what i get in ant
[checkstyle] [class]:0: Got an exception - java.lang.NoClassDefFoundError: com/onuspride/codetools/common/classpath/criteria/ClassNameCriteriaCollector
Im stumped. Ive checkd all the dependencies of my jar, they are all in the classpath, I don't understand how it can find one class file but not another in the same jar. Ive done all my dirty little tricks and I just don't get it.
any ideas?
You can do it like following :
Create plugin project and add your custom checks there.
Make appropriate changes to plugin.xml, checkstyle_packages.xml.
Export the project as Deployable Plug-ins and fragments (Export > Plug-in Developement)
Copy the jar file to Eclipse Plugin folde, so no need to install your custom check .
You can go through this tutorial for reference
To reduce effort, download a Sample Check, the file is here under the name net.sf.eclipsecs.sample
Just replace your source in src folder. Before replacing, refer this 3 files in src/net/sf/eclipsecs/sample/checks/ directory as you will need them in your com/onuspride/codetools/checkstyles/ directory :
checkstyle-metadata.properties
checkstyle-metadata.xml
messages.properties
After replacing the code, make appropriate changes in checkstyle_packages.xml file in src/ directory.
Extending Check is described nicely there.

How do I force MSBuild to clean or rebuild?

I am using MSBuild from a script to compile my project. I have noticed that it just does a build and not a clean/rebuild.
I have the following:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
<Target Name="Build">
<MSBuild Projects="$(MSBuildProjectDirectory)\myproj.csproj" Targets="Build" Properties="OutputPath=$(MSBuildProjectDirectory)\..\bin\" />
</Target>
How do I force a clean/rebuild?
"%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild" Project.sln
/p:Configuration=Release /t:Rebuild
Change
<MSBuild Projects="$(MSBuildProjectDirectory)\myproj.csproj"
Targets="Build"
Properties="OutputPath=$(MSBuildProjectDirectory)\..\bin\" />
to
<MSBuild Projects="$(MSBuildProjectDirectory)\myproj.csproj"
Targets="Clean;Build"
Properties="OutputPath=$(MSBuildProjectDirectory)\..\bin\" />
or
<MSBuild Projects="$(MSBuildProjectDirectory)\myproj.csproj" Targets="Rebuild"
Properties="OutputPath=$(MSBuildProjectDirectory)\..\bin\" />
For more details, look at the MSBuild Task documentation.
Always Try to use
<MSBuild Projects="$(MSBuildProjectDirectory)\myproj.csproj"
Targets="Clean;Build"
Properties="OutputPath=$(MSBuildProjectDirectory)\..\bin\" />
Because according to this MSDN article, when you have multiple projects in your solution using "Rebuild" as the target, may cause clean and build to happen in parallel manner. Which may cause problems in project dependencies.
But when you use "Clean and Build" as the target, build will start only after all the projects are cleaned.

Help Updating XML file using MSBuild Extensions 4 with namespaces

I'm having some trouble getting MSBuild extensions 4.0 to update an XML file once a namespace is involved.
When I have a simple XML file with no namespace then fine, but once i attempt to update an xml file that has a namespace set, then nothing happens .. notice there is no error tho.
Here are the simple ones that work fine
<Project>
<PropertyGroup>
<ApplicationVersion>5.1.500.16</ApplicationVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationVersion>old</ApplicationVersion>
</PropertyGroup>
</Project>
and project file
<Project ToolsVersion="4.0" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TPath>C:\Program Files\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>
<AssemblyVersion>5.1.500.18</AssemblyVersion>
</PropertyGroup>
<Import Project="$(TPath)"/>
<Target Name="Default">
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="RemoveElement" " File="c:\build\test.csproj" XPath="/Project/PropertyGroup[1]/ApplicationVersion" />
</Target>
</Project>
Wheras these dont do anything !
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://mynamespace">
<PropertyGroup>
<ApplicationVersion>5.1.500.16</ApplicationVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationVersion>old</ApplicationVersion>
</PropertyGroup>
</Project>
and
<Project ToolsVersion="4.0" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TPath>C:\Program Files\MSBuild\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>
<AssemblyVersion>5.1.500.18</AssemblyVersion>
</PropertyGroup>
<Import Project="$(TPath)"/>
<ItemGroup>
<Namespaces Include="Mynamespace">
<Prefix>me</Prefix>
<Uri>"http://mynamespace"</Uri>
</Namespaces>
</ItemGroup>
<Target Name="Default">
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="RemoveElement" Namespaces="#(Namespaces)" File="c:\build\test.csproj" XPath="//me:Project/PropertyGroup[1]/ApplicationVersion" />
</Target>
</Project>
So what's the deal ? what am i missing ? Is it the formatting of the XPath in the second instance ? I've tried all kinds of variations.
Try this:
<Target Name="Default">
<MSBuild.ExtensionPack.Xml.XmlFile TaskAction="RemoveElement" Namespaces="#(Namespaces)" File="c:\build\test.csproj" XPath="//me:Project/me:PropertyGroup[1]/me:ApplicationVersion" />
</Target>
(namespace prefix before each xpath element)
In addition to the advice given in the other answer, remove the quotes from the Uri metadata in the Namespace item.
Note that according to the note for the prefix parameter in the MSDN documentation, specifing the empty string for the Prefix metadata will never work.

Using System.Data.Linq in a Razor view

I may have a fundamental misunderstanding of what is going on here, but I'm having an issue looping through a LinqToSQL class in my razor view:
<h3>Owners</h3>
#foreach (var ThisOwner in Prop.PropertyOwnerships.Where(p=p.bIsOwner.Value==true))
{
<div class="ODEditEntry">
...
I'm getting the following error:
Compiler Error Message: CS0012: The type 'System.Data.Linq.EntitySet`1' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
I tried putting #using System.Data.Linq at the top of the cshtml file but it is telling me that Linq doesn't exist in the System.Data namespace. This is obviously not true and, yes, I do have system.data.linq as a reference in my project.
Any Ideas here? Is a import needed? Can I just not do Linq style stuff in my razor views? That would seem....odd?
You need to import the namespace into your view by adding #using System.Data.Linq at the top of your view. However if you want it in all your views then you need to add <add namespace="System.Data.Linq" /> to the web.config in your Views folder:
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Data.Linq" />
</namespaces>
</pages>
</system.web.webPages.razor>
Although not relevent to your question you should really try to move this logic out of the view and into the controller, it will make things much easier to debug and means that your presentation is separated from your business logic.
What fixed it for me was to right click the System.Data.Linq assembly reference, then hit properties. In there set Copy Local to true.
Does your Linq-to-Sql datacontext exist outside of the web project (e.g. in another class library)? If so, where you have added a reference to that project it all builds fine, but in the Razor view you are trying to directly access a type from the System.Data.Linq assembly without referencing it in the web project. Try adding the reference to the main web project and see what you get.
You need to add a reference to System.Data.Linq in your project and/or in your Web.config.
I spent hours and hours googling and no solution worked but this is what helped...
Remove everything inside <assemblies> element in web.config!
<compilation targetFramework="4.7.2">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<!-- etc etc blah blah -->
</assemblies>
</compilation>
Either add System.Core in there, or even better, remove everything and change it to:
<compilation targetFramework="4.7.2"/>
Explanation
The System.Linq namespace is defined in System.Core, right? So we either need to add it to the <assemblies> list , or (because System.Core is always referenced in your root web.config located at "%Windir%/Microsoft.NET/v4.0.30319/Framework/whatever") remove everything from <assemblies> to prevent conflicts.