My problem is that I cannot code logs (the one who wrote down every action you do in your program). So I am asking how can you create logs, and another thing I have this code here. I think it is for creating logs but I don't know how to edit the things that must be edited in the codes below. Can someone help me?
public class LogWriter
{
private string m_exePath = string.Empty;
public LogWriter(string logMessage)
{
LogWrite(logMessage);
}
public void LogWrite(string logMessage)
{
m_exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
try
{
using (StreamWriter w = File.AppendText(m_exePath + "\\" + "LOGG.txt"))
{
Log(logMessage, w);
}
}
catch (Exception ex)
{
MessageBox.Show("new"+ex);
}
}
public void Log(string logMessage, TextWriter txtWriter)
{
try
{
txtWriter.Write("\r\nLog Entry : ");
txtWriter.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
txtWriter.WriteLine(" :");
txtWriter.WriteLine(" :{0}", logMessage);
txtWriter.WriteLine("-------------------------------");
}
catch (Exception ex)
{
MessageBox.Show("old"+ex);
}
}
}
I would suggest you look into a logging framework if it is practical for you to use something other than this class you have shown. Look at Serilog or even Nlog. They are well designed for thread safety and efficiency.
To use this class, or any class (that is not static) you create an instance with new:
LogWriter logger = new LogWriter("a message here..");
Unfortunately this class was designed so you cannot instantiate it without writing a log entry so you will get "a message here.." log written at this point.
Now that you have an instance you can call methods on it, for instance:
logger.LogWrite("This is a log message...");
You should be able to see your log entries in the LOGG.txt file in the same folder as your program.
Don't think of this in terms of just this logger. If you had more experience programming you would already know how to do this. A little time invested in tutorials will go a long way.
Related
I've written a simple (console)script in C# that recursively deletes files and folders in the given parameter ex: delete_folder.exe "C:\test"
I use this tiny piece of code during an uninstall to delete the remaining files after the uninstall.
The code on itself works fine, but I receive the error: System.IO.IOException: The process cannot access the file 'C:\test\test2' because it is being used by another process.
Just before this error the uninstaller stops and deletes a couple of services (created by the installer)
It seems to me that Windows still uses the folder test2. So my question is: How to check if a folder is in use by another process and how to stop that process from being there, to be able to delete the remaining folders.
The console application looks like this:
class Program
{
public static void log(string t)
{
File.AppendAllText("C:\\testlog.txt", DateTime.Now.ToString() + "----" + t + "\r\n");
}
static void Main(string[] args)
{
try
{
string path = args[0];
if (Directory.Exists(path) == true)
{
Directory.Delete(path, true);
}
else
{
Console.WriteLine("Dir not found!");
}
}
catch (Exception ex)
{
log(ex.ToString());
}
}
}
A try...catch might sound not too elegant (actually, basing the normal flow of an algorithm on this statement is inadvisable in most of the cases), but seems the only way through here. Bear in mind that there is no System.IO (direct) property telling whether an element is in use; and thus relying on this is the usual solution for this kind of problems (post about file in use). Sample code:
foreach (string dir in System.IO.Directory.GetDirectories(rootDirectory))
{
try
{
System.IO.Directory.Delete(dir);
}
catch
{
//There was a problem. Exit the loop?
}
}
I am using the YAX Serializer (current NuGet version). When I run this code:
void Main()
{
try
{
int zero = 0;
int result = 100 / zero;
}
catch (DivideByZeroException ex)
{
LogSaveException(ex);
}
}
public void LogSaveException(object value)
{
try
{
YAXSerializer serializer = new YAXSerializer(value.GetType());
string loggedString = serializer.Serialize(value);
Console.WriteLine(loggedString);
}
catch (StackOverflowException)
{
Console.WriteLine("Log Error", "Could Not Log object of type "
+ value.GetType().ToString() +" due to stack overflow.");
}
catch (Exception)
{
Console.WriteLine("Log Error", "Could Not Log object of type "
+ value.GetType().ToString());
}
}
The app ends on this line: string loggedString = serializer.Serialize(value);
I have tried to catch any exception that I can see would happen. But the app just ends.
I tried running it in LinqPad and it crashed LinqPad. I tried to debug the crash of LinqPad (even though I do not have the source, sometimes you can get some info from it.) When I did that it said that there was a StackOverflowException. But my catch statement did not catch it.
What would cause a total death like that? How how do I guard against it?
Stackoverflow exceptions have limited "catchability" in CLR > 2.0. See the blog post below for more details; the behavior you're experiencing is exactly what's described.
See: http://blogs.msdn.com/b/jaredpar/archive/2008/10/22/when-can-you-catch-a-stackoverflowexception.aspx
While annoying, this does make sense: if you've blown your stack, what would a consistent/safe/sane recovery look like?
Seems like a serious error with the YAXSerializer.
StackOverflowException cannot be caught (see here amongst others for reference) because there's rarely any recovery from such a serious error.
EDIT: or it's an error with the class you're serializing. Do you have a cyclic reference in the object you're passing in?
I'm creating a Class library where I can import the DLL in later projects and just call the below to send a DirectMessage to Twitter user. It works if I include the code directly in the Form1 class but I dont want that I want to be able to do something like in VB:
Dim dm as New SendDM
dm.SendDirectMessage(user, message)
and it go. Any ideas? Im not that familiar with C# so should I make it public? Put it in it's own class file like SendDM.cs or what?
private void SendDM(string user, string message)
{
if (message.Length == 0)
{
MessageBox.Show("Your tweet must be at least 1 character long!");
return;
}
try
{
// URL-encode the tweet...
string tweet = HttpUtility.UrlEncode(message);
// And send it off...
string xml = _oAuth.oAuthWebRequest(
oAuthTwitter.Method.POST,
"http://api.twitter.com/1/direct_messages/new.xml",
"?user=" + user + "&text=" + message);
}
catch (Exception ex)
{
MessageBox.Show("An error occurred while posting your tweet:\n\n" + ex.Message);
return;
}
message = String.Empty;
}
Yes you can. Create a "Class Library" project. Insert your code and compile it.
from a class library you should not use MessageBoxe to notify exceptions or validate input parameters, just throw the exception from the catch instead of return and throw ArgumentOutOfRangeException if input parameter doesn't validate.
Said this, you should have a public class SendDM and inside it a public method SendDirectMessage if you wish to use your VB code shown above to send the message.
Also, you do not need to reset message to String.Empty at the end of the SendDirectMessage method.
How would i go about to do this?
protected void Page_Load(object sender, EventArgs e)
{
try
{
doSomething();
}
catch (Exception ex)
{
// Here i would like to know that the page is "Problem.aspx"
// and that it was caused from the doSomething() function
}
}
private void doSomething()
{
logToSomething();
}
Exception object has a stack trace property, which tells you exactly where the error took place.
Also, check out Microsoft Enterprise Library (more specifically the Logging Block).
The logged errors provide a stack trace, among other things, letting you know exactly where the error occurred.
I'm using this little class to log errors, have a look on how i get the page and the function(Stacktrace):
public static class ErrorLog
{
public static void WriteError(Exception ex)
{
try {
string path = "~/error/logs/" + System.DateTime.Now.ToString("dd-MM-yyyy") + ".txt";
if ((!System.IO.File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))) {
System.IO.File.Create(System.Web.HttpContext.Current.Server.MapPath(path)).Close();
}
using (System.IO.StreamWriter w = System.IO.File.AppendText(System.Web.HttpContext.Current.Server.MapPath(path))) {
w.WriteLine(System.Environment.NewLine + "Log Entry : {0}", System.DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture));
var page = VirtualPathUtility.GetFileName(HttpContext.Current.Request.Url.AbsolutePath);
w.WriteLine("Error in: " + page);
string message = "Message: " + ex.Message;
w.WriteLine(message);
string stack = "StackTrace: " + ex.StackTrace;
w.WriteLine(stack);
w.WriteLine("__________________________");
w.Flush();
w.Close();
}
} catch (Exception writeLogException) {
try {
WriteError(writeLogException);
} catch (Exception innerEx) {
//ignore
}
}
}
}
It's entirely sufficient for me.
Note: converted from VB.NET, hence untested
You can determine all of that by parsing the Exception message.
Look at your message and use a regex to extract the information you need.
Another option that you may want to look into is ELMAH ( Error Logging Modules and Handlers for ASP.NET ) http://code.google.com/p/elmah/ . I guess it really depends on what your specific needs are.
Use log4net, for logging the error messages. For help look at these article 1 and article 2.
Whatever logging method you use, do something like this.(Hand typed may not compile)
try
{
DoignStuff();
}
catch( Exception ex)
{
Trace.WriteLine( "Exception in <Page Name> while calling DoingStuff() Ex:"+ ex.ToString() );
}
It will start with the page name & method (which is redundant, but makes life easier)
then it will convert the EX to a string which shows call stack and all kinds fo other good stuff and put it in the log file
Note: you have to Type the name of the page in the place of <Page Name> .
Log4Net and Elmah are great to make life easier too.
Probably a stupid question... but here goes anyway...
I have set up quartz, and can schedule jobs, and I can confirm that jobs (implementing the IJob interface) are working.
Looking at the documentation on the site, (Lesson 3 of the tutorial):
The only type of exception that you are allowed to throw from the execute method is JobExecutionException.
I would like that when an exception occurs that I haven't explicitly handled, it should throw a JobExecutionException, so that I can log it in the 'parent' application. I have wrapped my code in a try catch, and have thrown the JobExecutionException, but now where to handle it?
I don't call the execute method anywhere, that is handled by Quartz (on a separate thread). So, how do I handle that error when it occurs. I don't really want to swallow the error in the Job
I solved this problem by using a base class to catch all the exceptions:
public abstract class JobBase : IJob
{
protected JobBase()
{
}
public abstract void ExecuteJob(JobExecutionContext context);
public void Execute(JobExecutionContext context)
{
string logSource = context.JobDetail.FullName;
try
{
ExecuteJob(context);
}
catch (Exception e)
{
// Log exception
}
}
}
Your Job class should like this:
public class SomeJob : JobBase
{
public SomeJob()
{
}
public override void ExecuteJob(JobExecutionContext context)
{
// Do the actual job here
}
}
Typically you would set up the execute method of your job as follows:
try
{
// the work you want to do goes here
}
catch (ExceptionTypeYouWantToHandle1 ex1)
{
// handle exception
}
catch (ExceptionTypeYouWantToHandle2 ex2)
{
// handle exception
}
// and so on
catch (Exception ex)
{
// something really unexpected happened, so give up
throw new JobExecutionException("Something awful happened", ex, false); // or set to true if you want to refire
}
At this point the scheduler itself will log the exception to wherever it is logging (based on the configuration).
As already mentioned, the correct way to "detect" JobExecutionException's on a global level is to implement and register an IJobListener and check if the JobExecutionException parameter in the JobWasExecuted() method is != null.
However, the problem I had (and judging from the additional comment of the OP, he faced this too) was that Quartz did not handle the JobExecutionException (as it should) which resulted in an unhandled exception killing the application.
So far, I was using the precompiled DLL from the Quartz.NET 2.0.1 release (.NET3.5) package. To get to the bottom of the problem, i referenced the Quartz project/sourcecode and to my astonishment it was suddenly working?!
As a point of interest, this is the Quartz library code that executes the IJob and handles the JobExecutionException:
try {
if (log.IsDebugEnabled) {
log.Debug("Calling Execute on job " + jobDetail.Key);
}
job.Execute(jec);
endTime = SystemTime.UtcNow();
} catch (JobExecutionException jee) {
endTime = SystemTime.UtcNow();
jobExEx = jee;
log.Info(string.Format(CultureInfo.InvariantCulture, "Job {0} threw a JobExecutionException: ", jobDetail.Key), jobExEx);
} catch (Exception e) {
// other stuff here...
}
The next thing was to reference my freshly compiled DLL direcly and this was working as well. Sadly i can't tell you why this works and i currently don't have any time to get into it any further, but maybe this helps someone. Maybe some else can confirm this and even contribute an explanation. It may have something to do with different target platforms (x86/64bit)?