.NET Web Service logging with Log4Net not working from separate client - c#

In a basic .NET web service (asmx) which I am building locally, I'm trying to log using Log4NET to a file. This works fine if I fire up debugging mode in Visual Studio and test the service using the wsdl/test pages provided. But if I try using a separate client (I made a C# console app to call the service), I see the expected response, but get NO logging.
(The separate client code is listed below. I had to import a reference to the built DLL of the web service.)
I'm a bit new to this, but I speculate the issue is because outside of the VS server or IIS (which I am stuck without), Global.asax is not used (which contains my initialization command for logging). But I need to test from an external client. How can I get Global.asax to initialize from the client application perspective, or how can I avoid needing to? Does this sound like it would solve my logging issue?
Global.asax in my web service project contains this statement:
protected void Application_Start(object sender, EventArgs e)
{
log4net.Config.XmlConfigurator.Configure();
}
And my separate client (console) application looks like this:
static void Main(string[] args)
{
MyWebService proxy = new MyWebService();
MyWebService.Request request = new MyWebService.Request();
request.Type = "Test";
MyWebService.Response response = proxy.GetResponse(request);
Console.WriteLine("RESPONSE CODE: " + response.StatusCode);
Console.WriteLine("RESPONSE MSG: " + response.StatusMessage);
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true);
}
I'm also unclear how I would change this console app to reference the Visual Studio server instance (ex: localhost:1583/MyWebService.asmx?op=GetResponse) instead of creating a proxy instance of the web service. I think that would also do the trick, since the Visual Studio server utilizes Global.asax, no?

The simpler way
would be to move the log4net initialization inside static void Main:
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
}
Don't forget to include log4net configuration in app.config file of your new host.
The better way
would be to move your service to separate project (it is already so, right?) so it is complied into it's own assembly. Than apply
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
attribute to the assemlyInfo.cs. Refer to log4net configuration manual for details (search for word assembly on the page). This way is better, because you'll not have to add that
log4net.Config.XmlConfigurator.Configure();
into the initialization of all host environments you have.
But make sure you have your log4net configuration in app.config, web.config or whatever configuration file you have.

Related

Could not start Windows Service, Error 1064

I wrote a Windows Service to run on Win10, and it worked perfectly fine until I decided to change it a bit. I rewrote some logic, tested it in both Debug and Release configurations, and everything was fine. Then I uninstalled the current version of the service using installutil.exe /u %servicename.exe% and reinstalled it again using installutil.exe %servicename.exe%.
For some reason, this new version cannot start, and it crashes with Error 1064. This is the full error text:
Windows could not start %servicename% service on Local Computer. Error 1064: An exception occurred in the service when handling the control request.
The last time I installed this service, I ran into some difficulties, but quickly fixed them by changing the Log On properties. This time, it is not working. Please help with this issue.
Thanks.
Update 1
Here are my Main() and OnStart() service methods:
Main()
static void Main()
{
#if DEBUG
var service = new SalesforceToJiraService();
service.OnDebug();
Thread.Sleep(Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new SalesforceToJiraService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
OnStart()
protected override void OnStart(string[] args)
{
this.ConfigureServices();
this.timer.Start();
this.logger.Information("SalesforceToJira service started.");
}
Update 2
More code:
ConfigureServices()
protected void ConfigureServices()
{
this.configuration = ConfigurationHelper.LoadConfiguration(ConfigurationPath);
this.logger = ConfigurationHelper.ConfigureLogger(this.configuration.Logs.LogsPath);
this.timer = ConfigurationHelper.ConfigureTimer(this.configuration.ProcessInterval.TotalMilliseconds,
(sender, eventArgs) => this.ProcessCasesAsync(sender, eventArgs).GetAwaiter().GetResult());
this.salesforceClient = new SalesforceCliClient(this.configuration.Salesforce.CliPath);
this.jiraClient = Jira.CreateRestClient(
this.configuration.Jira.Url,
this.configuration.Jira.Username,
this.configuration.Jira.Password);
}
I'm using Newtonsoft.JSON for deserializing a JSON configuration file, Serilog for logging, System.Timers.Timer for periodic events, AtlassianSDK for the Jira API and some wrappers over Salesforce CLI for Salesforce.
Thanks to #Siderite Zackwehdex's comment, I was able to find the full stack trace of the underlying exception in EventViewer, under:
Windows Logs\Application
In my case, my service is named "HttpDispatcher", which appears in the "Source" column in the top pane.
I could see immediately it was due to a dependency issue where my .NET 4.7.2 project was not pulling across my .NET Standard references. (That ol' chestnut).
I faced the same issue. The reason was I forgot to set the Database connection properly in configurations.
I had this exact same error 1064 starting my service. For me the user I had the service registered as was not a valid user in the database. Once added, it worked great.
I also had the same error in my Windows Service.
The reason was it can't read a configuration parameter, so it crash.
Adding some validation (bugfixing), the Windows Services can start it correctly.
In my case the error was due to issues with Event log name
It got fixed after I went to RegEdit and deleted old service name from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
I have also faced this issue. In my case it is due to connection fail with the data base. I think it is due to code throw the exception.
My error :
Windows could not start the service1 service on local computer.
Error 1064: An exception occured in the service when handling the control request
I corrected my issue by updating the third party DLL.
I faced the same issue, here is how I resolved it after troubleshooting.
If you are running service on the Server with multiple users, make
sure to run the service as admin user. Click on the service
properties and then on Log on tab click on this account and provide
the admin user name and password.
And If your service is accessing some shared drive, then make sure
you have a general user on all servers for accessing the shared
drives and add the user as local admin as well.
For me it happened when I tried to restart a process. Turned out the process was hanging in 'Stopping' so I had to kill it manually via command line and the PID.

How to integrate topshelf to an existing windows service project?

I want to be able to use the TopShelf debugging abilities of my service in Visual Studio.
A lot of the examples and documentation out there refer to creating a Windows Console project in Visual Studio first, and then adding TopShelf, OWIN, etc
However, in my case I already have a perfectly good and working Windows Service project called QShipsService.sln, etc... and it uses a simple Connected Service (admittedly to old SOAP legacy services).
Can someone please direct me or provide an example of how to use TopShelf, with an existing non-Console like project?
I found my own solution...
The assumption I made was the default Windows Service project defaulting to wanting to register the program as a service and kick off the OnOpen() and OnClose() methods, once the service is running.
In my case I wanted to re-use an existing service that was based on a Timer(), and it would kick in every 4 hours to call a SOAP call and return some data. What I didn't realise was the ServiceConfigurator was trying to call its own Open() and Close() methods.
So I commented out the OnOpen and OnClose methods and allowed the configurator to call my worker process via Open() method instead, which is what I was meant to have done the first time!
For the noobs out there like me, here is the code...
//using System.ServiceProcess;
using Topshelf;
namespace QShipsService
{
static class Program
{
static void Main(string[] args)
{
HostFactory.Run(
configure =>
{
configure.Service<QShipsService.QshipsService>(
service =>
{
service.ConstructUsing(s => new QShipsService.QshipsService());
service.WhenStarted(s => s.QStart());
service.WhenStopped(s => s.QStop());
});
//Setup Account that window service use to run.
configure.RunAsLocalSystem();
//add details and names about the service
configure.SetServiceName("QshipsService");
configure.SetDisplayName("QshipsService");
configure.SetDescription("QshipsService Windows Service to extract data from the QSHIPS SOAP service. Data is recorded and maintained inside the SPOT's database in POT-DB.");
});
//## USE THIS IF WE'RE NOT USING TOPSHELF !! ##
// //this loads and starts the QshipsService (see QshipsService.cs program)
// ServiceBase[] ServicesToRun;
// ServicesToRun = new ServiceBase[]
// {
// new QShipsService.QshipsService()
// };
// ServiceBase.Run(ServicesToRun);
}
}
}

Calling a Console application through a Window Service

I have a Window Service , that is running on my machine . I have separate console application in the same solution that is performing some functionality. In order to access the functions of the console application , I have add the *.exe file of the console application as a reference to the Window Service project.
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
// TODO: Insert monitoring activities here.
EventLog.WriteEntry("Monitoring the System", EventLogEntryType.Information);
string[] arr = new string[] { };
ConsoleApplication.Program.Main(null);
}
The Console application works perfectly file if I directly run through Visual Studio. However , If I call the Main() method from the Window Service I am getting a null pointer exception.
public static void Main(string[] args)
{
try
{
//CODE BREAKS HERE ON READING FROM CONFIG FILE
string genesis_sel= ConfigurationSettings.AppSettings["genesis_sel"].ToString();
}
catch (Exception ex)
{
//Exception code
}
}
Below is a snapshot of the Console application Project running in Visual Studio.
I am not sure what's causing the code to break while accessing the main method from a Window service.
Any suggestions?
Update: Added snapshot of the config file. I don't believe it's a rad access issue from the configuration file as it is reading correctly when I run the console application alone. There is an initialization issue when I access it through the window Service.
UPDATE Replaced the main method with a single event log , but still getting the same exception.
When you call the method it is running as part of your service, so it uses Environment and settings from your service. That means that you should have correct data in AppSettings of your service project. To bring more clarity: In this case function Main is part of your service and not a separate application root.
Otherwise you can run your console as separate process, but in that case you are loosing part of Control functions.
I would suggest, to separate common logic in a separate project/dll and call functions from it, it will be more clean and not so confusing

how to host silverlight project local

i want to debug my program but i can't host my silverlight project in VS 2010
here is the message that the VS send to me:
"the Silverlight project you are about to debug uses web service. Call to the web service will fail unless the Silverlight is host and launched from the same web project contains the web service"
when I search about it in the web i saw that the problem is that I'm not doing it local
so when I tried to change this line
endpoint address="http://xxx.xx.x.x/WebService/Service1.svc"
to
endpoint address="http://localhost/WebService/Service1.svc"
on this file:
ServiceReferences.ClientConfig
update!!
i tried now to do it like this:
endpoint address="http://localhost:54502/Service1.svc"
and i got and error that says:
the remote server returned an error:NotFound
here:
public int EndAddParticipant(System.IAsyncResult result) {
object[] _args = new object[0];
int _result = ((int)(base.EndInvoke("AddParticipant", _args, result)));
return _result;
what should i do to change it?
i saw that i need to turn on the debug in web.config file but it was already on.
You didn't explain well so here are a bunch of answers:
When you created your solution, you should have told it to host in a web site.
You can do this after the fact but it is a lot of work (for a new guy), you're better off starting over and copying your code from your silverlight project.
If you did but you are trying to connect to another web site as your web service, you will have to implement a Cross Domain configuration file. This opens a big security hole though.
If you have the 2 projects, but your issue is just the "ServiceReferences.ClientConfig" file not pointing the the right server, you need to include the PORT when debugging locally. It should look something like this:
http://localhost:12345/Service1.svc
Where 12345 is the port of your local web service. You can find this out by looking at the "Web" tab of your project properties.
Hope one of these does it. If not, please provide a little more info, like all the important stuff behind the phrase, "it didn't work"!

MSDN WCF service example not working

This question is a followon from my previous where I have since discovered that it is not working 100% on my computer: WCF service not running on non-dev machine
I'm working through this example:
http://msdn.microsoft.com/en-us/library/ff649818.aspx
It turns out that the InstallUtil step isn't really working here. I've discovered that if VS2010 has the project open, and you go to add a service reference like in step 8 of the tutorial, VS2010 actually starts up the service host and therefore a reference is created.
Here's how i've debugged so far:
Install the service as per InstallUtil, close down VS2010 solution; then open a completely different solution (TESTWCF) Try and add a service reference and it fails - cannot find at the specified address
Open WCFServiceLibrary1 project again as a separate instance of VS2010. Try and add a service reference to TESTWCF and it fails.
Within WCFServiceLibrary1, attempt step 8 - add a service reference. This causes the service host to start and the service is found.
With service host still running, in TESTWCF I then try and add service and it works.
Close down the service host and try and add reference in TESTWCF and it doesn't work again.
This all seems to be totally independant of the service running or not running as installed by InstallUtil.
I've also verified this through the creation of a new virtual server from scratch and loading things on one by one. And only when VS2010 was installed did it start to work - when I observed above.
Any ideas ?
WCF services can be self-hosted in an application (such as a console or a Windows Forms application)
I think you are over complicating it, you don't have to even install it with InstallUtil.
InstallUtil installs it to run as windows service, and you can make console application which will be serving as WCF service.
You have to import:
System.ServiceModel
System.ServiceModel.Web
System.Web.Services
I think those with web will be needed if you want to use it as web service with get and post.
Then you need to specify contract for client and server.
[ServiceContract(Name = "SomeService", Namespace = "http://some.domain.com/some/someservice",SessionMode=SessionMode.Required)]
public interface ISomeService
{
[OperationContract]
string Execute(string expression);
}
You have contract and now you have to implement it in service. nothing special in there just use this interface.
What is very important is app.config, you have to specify it well for client and for service. In config you have all stuff that points to service.
In client you have to add service as reference, it should find it as in point 8 but only if you have configs ok!
In client just do something in code like that:
using (ChannelFactory<ISomeService> channel = new ChannelFactory<ISomeService>("SomeService"))
{
ISomeService svc = channel.CreateChannel();
svc.Execute("my expression to evaluate by the service");
}
Try to make it easiest possible way without InstallUtil and such, it doesn't have to be windows service to serve stuff over network.
Success ! After like 4 days of effort on this, the MSDN tutorial has a fatal flaw.
In the first step of the tutorial you create a wcf service library and by default it names the service Service1. In step 2.6 of the tutorial you are asked to specify the base address:
net.tcp://localhost:8523/Service1
Step 3 you are asked to create a new windows service, and by default this is also called Service1.
In step 5.2 you are asked to make a reference to System.ServiceModel and to WcfServiceLibrary1.
In step 5.6 you replace the Onstart Method to start the service and, Step 8 shows the final code as being:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using WcfServiceLibrary1;
namespace WindowsService1
{
public partial class Service1: ServiceBase
{
internal static ServiceHost myServiceHost = null;
public WCFServiceHost1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
if (myServiceHost != null)
{
myServiceHost.Close();
}
myServiceHost = new ServiceHost(typeof(Service1));
myServiceHost.Open();
}
protected override void OnStop()
{
if (myServiceHost != null)
{
myServiceHost.Close();
myServiceHost = null;
}
}
}
}
The crucial line of code which is wrong is:
myServiceHost = new ServiceHost(typeof(Service1));
Well it might behave differently in VS2008 or 2005 or maybe it's a config in VS2010 however, my VS2010 interprets Service1 to be that of the containing class ie:
WindowsService1.Service1
Whereas it should in fact be:
WcfServiceLibrary1.Service1
I noticed that 4 days ago but figured I didn't know enough about WCF and I was wrong somehow - esp when it appeared to work 'cause of VS2010 starting it up itself.

Categories