Modify tomcat server.xml config using sed - regex

I am making an Ubuntu package that depends on Tomcat7 through HTTPS. To make it convenient for our customers, I would like the install script of the package enable HTTPS in Tomcat7. This is pretty easy to do manually; in the file /etc/tomcat7/server.xml, one needs to uncomment the following block:
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
How could I do this from a shellscript? Preferebly in a way that it still works for slight modifications of the exact pattern. I think the rule would be something along the lines of search for '<Connector port="8443"' and then remove <!-- and --> before and after the block.

Consider apply a patch on your server.xml.
Generating a patch file:
diff -ruN server.xml.old server.xml.new > mydiff.patch
Where server.xml.old is the original file, and server.xml.new is the file as you want.
The patch (mydiff.patch) will look like this:
--- server.xml.old 2011-10-29 04:03:25.000000000 -0300
+++ server.xml.new 2011-10-29 04:04:03.000000000 -0300
## -1,10 +1,10 ##
(...)
- <!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
- --->
(...)
Then, just apply the patch:
patch server.xml mydiff.patch
You can run the patch command with the flag -N. Thus, it will skip files that seems already patched.

diff should most probably be the tool of your choice. But if the original config file is changed frequently, diff could not be able to apply your script in future versions.
sed also has the ability to read in more than one line. You may want to look at this example that also deals with modifying an xml document.

This might work:
sed -nr '/^<!--/,/^-->/!{p;b};/^<!--/{h;d};H;/^-->/{x;/<Connector port="8443"/{s/(^<!--\s*\n|\n\s*-->)//g};p}'
This ignores all non-comment lines. Saves the comment lines in hold space then deletes the start/end comment delimiters if the comment contains <Connector port="8443" and then prints the comment/non-comment.

Related

Powershell regex for replacing text between two strings

I am trying to use a powershell script to change the password between two strings, I am running into two issues.
A complex password seems to break my regex, If I use something as simple as "TestPassword" the regex does what I expect. However using a more complex password "6QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI=" it breaks and results in
SSLEnabled="true" keystoreFile="C:\cert.pfx" $16QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI=" keystoreType="PKCS12"/>
instead of
SSLEnabled="true" keystoreFile="C:\cert.pfx" keystorePass="6QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI=" keystoreType="PKCS12"/>
I want to be less specific for the second match grouo, for example at the moment I must specify '" keystoreType' but I would prefer to be less specific and only specify the ending quote. This way if I change the position of the keystoreType parameter in the future I don't have to worry about changing the regex to suit.
Bellow is my powershell as it stands:
#Set new password in server.xml
$pass='6QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI='
$server_xml=".\server.xml"
(Get-Content $server_xml) -replace '(keystorePass=")(.*)(" keystoreType)',('$1{0}$3' -f "$pass") | Set-Content $server_xml
Bellow is an extract from my xml:
<Connector port="443" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^\`"<>"
maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
acceptCount="100" disableUploadTimeout="true" bindOnInit="false" secure="true" scheme="https"
proxyName="test.example.com" proxyPort="443"
SSLEnabled="true" keystoreFile="C:\cert.pfx" keystorePass="123abc" keystoreType="PKCS12"/>
Parse
As pointed out by #the four bird and #codextor in the comments; peeking and poking directly into a serialized string (e.g. XML) using string methods (like -Replace) is a bad idea. Instead you should use the related parser for searching and replacing which has an easier syntax, takes care of both your issues and other pitfalls (e.g. double quotes $pass='Test"123').
Security
There is even a protentional security risk by ignoring the related parsers as a user (which is assumed only allowed to supply a password) could inject a new property in your xml (connector) by supplying a password like:
$pass = 'MyPass" maxParameterCount="0'
Examples
$Xml = [Xml]'<Connector port="443" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^\`"<>" maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false" maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443" acceptCount="100" disableUploadTimeout="true" bindOnInit="false" secure="true" scheme="https" proxyName="test.example.com" proxyPort="443" SSLEnabled="true" keystoreFile="C:\cert.pfx" keystorePass="123abc" keystoreType="PKCS12"/>'
$Xml.Connector.keystorePass = '6QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI='
$Xml.Connector
port : 443
relaxedPathChars : []|
relaxedQueryChars : []|{}^\`"<>
maxThreads : 150
minSpareThreads : 25
connectionTimeout : 20000
enableLookups : false
maxHttpHeaderSize : 8192
protocol : HTTP/1.1
useBodyEncodingForURI : true
redirectPort : 8443
acceptCount : 100
disableUploadTimeout : true
bindOnInit : false
secure : true
scheme : https
proxyName : test.example.com
proxyPort : 443
SSLEnabled : true
keystoreFile : C:\cert.pfx
keystorePass : 6QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI=
keystoreType : PKCS12
$Xml.OuterXml
<Connector port="443" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^\`"<>" maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false" maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443" acceptCount="100" disableUploadTimeout="true" bindOnInit="false" secure="true" scheme="https" proxyName="test.example.com" proxyPort="443" SSLEnabled="true" keystoreFile="C:\cert.pfx" keystorePass="6QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI=" keystoreType="PKCS12" />
Addendum
(based on the additional info in the comments)
If there are more connectors in your xml, as e.g.:
$Xml = [Xml]'
<Connectors>
<Connector
port="80"
keystorePass="Pass1" />
<Connector
port="443"
keystorePass="Pass2" />
</Connectors>'
You might address the connectors like:
$Xml.Connectors.Connector[0].keystorePass = 'Pass80'
$Xml.Connectors.Connector.Where{ $_.port -eq '443' }.SetAttribute('keystorePass', 'Pass443')
$Xml.OuterXml
<Connectors><Connector port="80" keystorePass="Pass80" /><Connector port="443" keystorePass="Pass443" /></Connectors>
This person had a similar issue that I was able to use the regex in my code:
Hide passwords in string
I ended up with the following:
#Set new password in server.xml
$pass='6QAfD5PmMhWzUxTq1FO1bGJQQXRXu6tizN29h6MRUSI='
$server_xml=".\server.xml"
(Get-Content $server_xml) -replace '(?:(?<=keystorePass=")\S+(?="))',("$pass") | Set-Content $server_xml

aws web service not available on the internet

In unix using putty I am able to get a result:
curl http://localhost:8080/products-ut-wo-db/rest/products
In security group I have inbound: 8080
In /home/ec2-user/java/tomcat9/webapps/manager/META-INF/context.xml I comment out the valve following:
I tried these url nothing come:
http://ec2-18-236-111-143.us-west-2.compute.amazonaws.com:8080/products-ut-wo-db/rest/products
http://ec2-18-236-111-143.us-west-2.compute.amazonaws.com:8080
Here is my netstat -nat:
Here is the /home/ec2-user/java/tomcat9/conf/server.xml:
Here is my /home/ec2-user/java/tomcat9/conf/server.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
This connector uses the NIO implementation. The default
SSLImplementation will depend on the presence of the APR/native
library and the useOpenSSL attribute of the
AprLifecycleListener.
Either JSSE or OpenSSL style configuration may be used regardless of
the SSLImplementation selected. JSSE style configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
This connector uses the APR/native implementation which always uses
OpenSSL for TLS.
Either JSSE or OpenSSL style configuration may be used. OpenSSL style
configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" >
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
Any help or hint will be greatly appreciated it.
It seems that tomcat is not binding to a IPv4 address (according to netstat output, it is only bound to IPv6 - check first column).
In order to configure tomcat to bind to IPv4, refer to this answer. It describes the proper way to configure your tomcat JVM to preferIPv4Stack and preferIPv4Addresses.

Sitecore Unicorn item synchronisation

I am using Unicorn for item serialization to my local file system. In this configuration I have a collection which contains a lot of items. These items don't have to be serialized to my file system, but the root folder should.
So I included the root folder, but how can I configure Unicorn to skip its child items?
<include database="master" path="/sitecore/content/mycollection" />
I would expect something like
<include database="master" path="/sitecore/content/mycollection" excludeChilds="true />
or
<include database="master" path="/sitecore/content/mycollection"><exclude "*" /></include>
If you are using Unicorn 3, it is now possible to skip child items by adding a trailing slash.
<include database="master" path="/sitecore/content">
<exclude path="/sitecore/content/" />
</include>
See: http://kamsar.net/index.php/category/Unicorn/#Exclude_all_children_with_the_predicate for more information.
It's not possible the way you're proposing, although it doesn't seems so hard looking at the code to implement it that way. But it might be useful to exclude the unnecessary items by template. This can be achieve by adding the following exclude tags inside the include tag.
<exclude template="Page" />
<exclude templateid="{8EF706F3-71D1-4EE2-BADF-99018AF186C9}" />
In unicorn 3.1
<include database="master" path="/sitecore/content/mycollection">
<exclude children="true" />
</include>
Source: https://kamsar.net/index.php/2016/01/Unicorn-3-1-Released/
Note: elkaz answer with trailing slash works too but this is the preferred way since 3.1 according to kamsar's blog post.

sed replace range of lines with a single word

I tried my best to get this and had little luck, I have following file and I want to replace
first “<Connector port="8080"” xml block with ‘xxxx’
Before :
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
After :
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
xxxx
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
I got the matching string to print using following sed command :
sed -n '/<Connector port="8080"/,/>/p' filename
However I’m unable to develop this to get above output.
This sed should do the trick on your sample input (but gets overzealous if you have more than one <Connector port="8080" section):
sed '/<Connector port="8080"/,/>/{ s/<Connector.*/xxxx/; t; d }'
But handling this robustly calls for an XML parser. Example:
#!/usr/bin/env ruby
require 'rexml/document'
include REXML
d = Document.new(File.read(ARGV[0]))
e = d.get_elements('//Connector[#port="8080"]').first
if !e.nil?
e.parent.insert_after(e, Text.new('xxxx'))
e.parent.delete(e)
end
File.open(ARGV[0],'w'){|f| f.print(d) }
sed '/<Connector port="8080"/,/>/ {
N
/>/ s/.*/xxxx/
}' YourFile
load the section of connector before changing it to xxxx, this allow you to eventually test something on it (but not better than pobrelkey if not)
Thanks all for the answers , they worked well .Appriciate it:
Also i got following from one of my firend which also a answer to this using awk
awk '/<Connector port/ {
print "abc"
getline
do {
getline
} while (index($0, ">") == 0)
getline
}
// { print $0}' < 1.txt

Log4Net "Could not find schema information" messages

I decided to use log4net as a logger for a new webservice project. Everything is working fine, but I get a lot of messages like the one below, for every log4net tag I am using in my web.config:
Could not find schema information for
the element 'log4net'...
Below are the relevant parts of my web.config:
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level: %message%newline" />
</layout>
</appender>
<logger name="TIMServerLog">
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
</logger>
</log4net>
Solved:
Copy every log4net specific tag to a separate xml-file. Make sure to use .xml as file extension.
Add the following line to AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "xmlFile.xml", Watch = true)]
nemo added:
Just a word of warning to anyone
follow the advice of the answers in
this thread. There is a possible
security risk by having the log4net
configuration in an xml off the root
of the web service, as it will be
accessible to anyone by default. Just
be advised if your configuration
contains sensitive data, you may want
to put it else where.
#wcm: I tried using a separate file. I added the following line to AssemblyInfo.cs
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
and put everything dealing with log4net in that file, but I still get the same messages.
You can bind in a schema to the log4net element. There are a few floating around, most do not fully provide for the various options available. I created the following xsd to provide as much verification as possible:
http://csharptest.net/downloads/schema/log4net.xsd
You can bind it into the xml easily by modifying the log4net element:
<log4net
xsi:noNamespaceSchemaLocation="http://csharptest.net/downloads/schema/log4net.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
I had a different take, and needed the following syntax:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.xml", Watch = true)]
which differs from xsl's last post, but made a difference for me. Check out this blog post, it helped me out.
Just a word of warning to anyone follow the advice of the answers in this thread. There is a possible security risk by having the log4net configuration in an xml off the root of the web service, as it will be accessible to anyone by default. Just be advised if your configuration contains sensitive data, you may want to put it else where.
I believe you are seeing the message because Visual Studio doesn't know how to validate the log4net section of the config file. You should be able to fix this by copying the log4net XSD into C:\Program Files\Microsoft Visual Studio 8\XML\Schemas (or wherever your Visual Studio is installed). As an added bonus you should now get intellisense support for log4net
In Roger's answer, where he provided a schema, this worked very well for me except where a commenter mentioned
This XSD is complaining about the use of custom appenders. It only allows for an appender from the default set (defined as an enum) instead of simply making this a string field
I modified the original schema which had a xs:simpletype named log4netAppenderTypes and removed the enumerations. I instead restricted it to a basic .NET typing pattern (I say basic because it just supports typename only, or typename, assembly -- however someone can extend it.
Simply replace the log4netAppenderTypes definition with the following in the XSD:
<xs:simpleType name="log4netAppenderTypes">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Za-z_]\w*(\.[A-Za-z_]\w*)+(\s*,\s*[A-Za-z_]\w*(\.[A-Za-z_]\w*)+)?"/>
</xs:restriction>
</xs:simpleType>
I'm passing this back on to the original author if he wants to include it in his official version. Until then you'd have to download and modify the xsd and reference it in a relative manner, for example:
<log4net
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../Dependencies/log4net/log4net.xsd">
<!-- ... -->
</log4net>
Actually you don't need to stick to the .xml extension. You can specify any other extension in the ConfigFileExtension attribute:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", ConfigFileExtension=".config", Watch = true)]
#steve_mtl: Changing the file extensions from .config to .xml solved the problem. Thank you.
#Wheelie: I couldn't try your suggestion, because I needed a solution which works with an unmodified Visual Studio installation.
To sum it up, here is how to solve the problem:
Copy every log4net specific tag to a separate xml-file. Make sure to use .xml as file extension.
Add the following line to AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "xmlFile.xml", Watch = true)]
For VS2008 just add the log4net.xsd file to your project; VS looks in the project folder as well as the installation directory that Wheelie mentioned.
Also, using a .config extension instead of .xml avoids the security issue since IIS doesn't serve *.config files by default.
Have you tried using a separate log4net.config file?
I got a test asp project to build by puting the xsd file in the visual studio schemas folder as described above (for me it is C:\Program Files\Microsoft Visual Studio 8\XML\Schemas) and then making my web.config look like this:
<?xml version="1.0"?>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option in Visual Studio.
A full list of settings and comments can be found in
machine.config.comments usually located in
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<appSettings>
</appSettings>
<connectionStrings>
</connectionStrings>
<system.web>
<trace enabled="true" pageOutput="true" />
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="true" />
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="Windows" />
<customErrors mode="Off"/>
<!--
<customErrors mode="Off"/>
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="On" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
</system.web>
<log4net xsi:noNamespaceSchemaLocation="http://csharptest.net/downloads/schema/log4net.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<!-- Please make shure the ..\\Logs directory exists! -->
<param name="File" value="Logs\\Log4Net.log"/>
<!--<param name="AppendToFile" value="true"/>-->
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
</layout>
</appender>
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="" />
<from value="" />
<subject value="" />
<smtpHost value="" />
<bufferSize value="512" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="WARN"/>
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger [%property] - %message%newline%newline%newline" />
</layout>
</appender>
<logger name="File">
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</logger>
<logger name="EmailLog">
<level value="ALL" />
<appender-ref ref="SmtpAppender" />
</logger>
</log4net>
</configuration>
Without modifying your Visual Studio installation, and to take into account proper versioning/etc. amongst the rest of your team, add the .xsd file to your solution (as a 'Solution Item'), or if you only want it for a particular project, just embed it there.
I noticed it a bit late, but if you look into the examples log4net furnishes you can see them put all of the configuration data into an app.config, with one difference, the registration of configsection:
<!-- Register a section handler for the log4net section -->
<configSections>
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
</configSections>
Could the definition it as type "System.Configuration.IgnoreSectionHandler" be the reason Visual Studio does not show any warning/error messages on the log4net stuff?
I followed Kit's answer https://stackoverflow.com/a/11780781/6139051 and it didn't worked for AppenderType values like "log4net.Appender.TraceAppender, log4net". The log4net.dll assembly has the AssemblyTitle of "log4net", i.e. the assembly name does not have a dot inside, that was why the regex in Kit's answer didn't work. I has to add the question mark after the third parenthetical group in the regexp, and after that it worked flawlessly.
The modified regex looks like the following:
<xs:pattern value="[A-Za-z_]\w*(\.[A-Za-z_]\w*)+(\s*,\s*[A-Za-z_]\w*(\.[A-Za-z_]\w*)?+)?"/>