.Net Application logging - c#

Hello all I have a scenario where i have one winform app as server and infinite number of winform apps as clients
basically each client connects to server and sends a string to server , server than do some calculations and return string back to client, but server have to connect to another server for calculation of that string and in response from that second server our main server stores the response in a string variable and after some specific time intervals it shows that string variable in a textbox but this string gets bigger and bigger after each calculation and hence my server some times starts consuming 1gb memory in task manager and 40% of my cpu usage , and when i removed the string variable my server was running on 45mb of memory and 0-4% of cpu usage i am using string variable like this
string Serverlog += datafetched + "cl"
i have also tried a string builder object but result is same so can any one help me to sort out things ( how can i save logs without consuming to much memory ) and one thing more logs will not be maitained in any file they are only for showing them into textbox

Best solution is to store your logging somewhere, database / file / winlogging / other
What kind of app are you running on the clients? Be aware that u use the AppendText function of the textbox. So dont use:
Textbox.Text += "additional info"
but use
Textbox.AppendText(teTonenTekst + Environment.NewLine);

While logging to a file is best, you mentioned you do not want that.
For UI based logging, I usually avoid a TextBox, and instead use a ListView or DataGridView with hidden gridlines. That way it is easy to truncate the amount of values to a limit, keeping only recent data in the control.
It is also easier to color code different types of logging data.

You can write the text in to the file or MSMQ or Telnet and clear the variable. While displaying the contents read from one of the above mentioned source.

You should be used text file for logging application actions.

I would suggest to store the logs in a file instead of keeping everythingin a variable. I personaly always do that by using a logging function which creates an individual log file for each user each day. Like that you have a better control over your logs and dont have to worry about your preformance problem. Have a look at this example:
internal static void WriteLog(string str, string clientNumber)
{
StreamWriter logWriter = null;
string todayDateString = DateTime.Now.Day.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Year.ToString();
string fullLogFileName = todayDateString + "_" + clientNumber + "_log.txt";
string LogPath = #"\\server\folder\Logs\";
string fullLogFilePathWithName = LogPath + fullLogFileName;
if (!File.Exists(fullLogFilePathWithName))
{
logWriter = new StreamWriter(fullLogFilePathWithName, true);
logWriter.WriteLine(DateTime.Now.ToString("d.MM.yyyy h:mm") + " - " + str);
logWriter.Flush();
}
else
{
logWriter = File.AppendText(fullLogFilePathWithName);
logWriter.WriteLine(DateTime.Now.ToString("d.MM.yyyy h:mm") + " - " + str);
logWriter.Flush();
}
logWriter.Dispose();
logWriter.Close();
}

.net already has built in support for tracing / logging:
http://msdn.microsoft.com/en-us/library/zs6s4h68.aspx
However, we use log4net, and I'm quite happy with it:
http://logging.apache.org/log4net/
From your question it is not quite clear if the log is displayed by the server or the client. However, log4net has support for logging over the net, e.g. an UPD Appender.

Related

Set up Scheuled Task to create Excel File and send email with attachment in C# Console application

I had a problem where a scheduled task would not send out an email with an attachment in a C# console application. It took me a long time to figure out the solution (it is working now), so I wanted to share what the two issues were so others can find the solution easily.
There were two problems:
1) When saving the file to the directory I could not use a relative directory like:
DirectoryInfo currentDir = new DirectoryInfo(Directory.GetCurrentDirectory());
attachmentPath = currentDir.Parent.Parent.FullName + #"\Reports\" + startDate.ToString("yyyy.MM.dd") + " - " + endDate.ToString("yyyy.MM.dd") + ".xlsx";
I had to explicitly set the directory like:
attachmentPath = #"E:\reports\Excel Automated Reports\WebEx Daily Report\ExcelReportAutomation\Reports\" + startDate.ToString("yyyy.MM.dd") + " - " + endDate.ToString("yyyy.MM.dd") + ".xlsx";
After, I did that the file was being created and saved but still was not emailing it out. If I sent out an email without an attachment then the email would go out. The way to fix this issue is by setting the Start in (optional) option in the edit action for the scheduled task.
I repeat this is not a question but I am trying to lay out a solution for people who come across the same issue.

How to delete duplicate lines written by page reload?

I write a log file and it always has a duplicate line (cause by page reloading I guess).
userName searched for: 'assembly' at: 3/24/2015 7:32:42 AM
userName searched for: 'assembly' at: 3/24/2015 7:32:43 AM
Here is my code for file writing:
using (StreamWriter streamWriter = File.AppendText(Server.MapPath("~/searchlog.txt")))
{
streamWriter.WriteLine(userRecord.name + " searched for: \'" + ProcessInputClause + "\' at: " + DateTime.UtcNow);
}
What would be a good way to get rid of this? I am thinking of using:
var lines = System.IO.File.ReadAllLines("...");
System.IO.File.WriteAllLines("...", lines.Take(lines.Length - 1).ToArray());
But this doesn't seem to work...
You shouldn't remove any record from your log. You need precisely know what happens in application to be able reproduce application bugs. Removing line from log can hide something very important.
In case there is need remove some duplication from log than there is probably some design smell.
You can try this:
var previoustext = new HashSet<string>();
File.WriteAllLines(destinationFile, File.ReadLines(sourceFile)
.Where(line => previoustext.Add(line)));
You should change the place you write your log since some modules of the page may call your script multiple times while loading one page.
I wouldn't log the search entries what I would do is insert into database the record that have been searched at what time and other info you need so it is even easier to make reports or statistics of searches done on your website.

Automatically Check if a webpage source code has changed

I am new to C#/WPF programming and I am trying to automatically update a local copy of a source code if the source code for a certain page has changed. Is there a way to check the source code say every other day without me having to go in manual do diff?
To get the source code for the website I have
Private bool getSourceCode(string UserInputSub)
{
//insert error catching..
using (WebClient webClient = new WebClient()) //Get source code of page.. user //enters URL
{
string s = webClient.DownloadString(UserInputSub);
string fixedString = s.Replace("\n", "\r\n");
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string FilePath = desktopPath + "\\SourceCode.txt";
System.IO.StreamWriter wr = new System.IO.StreamWriter(#FilePath);
wr.Write(fixedString);//writes to script
wr.Close();
}
return true;
}
This only runs once the program is being runned. I would like it so the user does not have the run teh program for it to update the txt it produces.
Add a timer to the project, set the interval to 86400000 ms(24 hs), and then in the tick event call your function,is not the best solution,better will be to add as a cron job or something, but if is a dedicated machine,sure it will work.
The simple solution would be to write a windows service that will fire once a day, and do this for you.
It'll add some complexity, but do what you want.
edit:
If you want this as part of the windows application, you can set a timer, or poll every x amount of time, but then your application needs to be open all the time for this to happen.
If you want to collect the data independently from the windows program who uses it, you'll have to have a separate service running in the background. Of course, you can have a simple console windows in the background that'll do it for you, but that so hackish that it should be illegal.

Writing a CSV log file

I have a Winforms program that needs to log data points into a .CSV file. It's fairly simple, date/time and a double (the data), and go to the next line.
Here's what I have so far (not working, I get an error saying the file is busy/already open - however, it's empty)
if (!Directory.Exists(SavePath.Text + "\\LOG"))
Directory.CreateDirectory(SavePath.Text + "\\LOG");
string LogFileName = SavePath.Text + "\\LOG\\Seeing-Log-" + TimeNow.ToString("yyyy-MM-dd") + ".csv";
if (!File.Exists(LogFileName))
File.Create(LogFileName);
string LogString = TimeNow.ToString("yyyy-MM-dd-_HH-mm-ss") + "," + FWHM_Value.ToString("F:");
File.AppendAllText(LogFileName, LogString + Environment.NewLine);
It's that last line that generates the error.
Any idea what I am doing wrong?
thanks
Steve
File.Create returns an open FileStream to the file that's just been created. Either change your code to work with FileStream in both the non-existent and existent file cases, or just close the file after creating it:
if (!File.Exists(LogFileName))
File.Create(LogFileName).Close();
But, of course, if you check the documentation for AppendAllText:
Appends the specified stringto the file, creating the file if it does not already exist.
You'll realise that the above two lines are completely redundant anyway and can be removed:
if (!Directory.Exists(SavePath.Text + "\\LOG"))
Directory.CreateDirectory(SavePath.Text + "\\LOG");
string LogString = TimeNow.ToString("yyyy-MM-dd-_HH-mm-ss") + "," + FWHM_Value.ToString("F:");
File.AppendAllText(LogFileName, LogString + Environment.NewLine);
You can even use the free looging tools. Here is one 'log4net'
You can also write the csv file using this. I am assuming currently you are not using logging tool. it will work for you without any code for implementation .
http://element533.blogspot.in/2010/05/writing-to-csv-using-log4net.html
Have a great day!!
Replace
File.Create(LogFileName);
with
File.Create(LogFileName).Close();
see this to create empty file.
The file is locked when you create it. Just update your code to this:
File.Create(LogFileName).Close();

Alternatives ways to getting the properties of the file?

Background:
I have a file monitoring service that watches for changes in the files on the local system using the FileSystemWatcher class and i am handling for events like Created,Deleted,Renamed. When these events are triggered,I would simply want to GET THE PROPERTIES OF THE FILE such as FileName,FileSize,CreationTime,LastAccessTime,LastWriteTime using the FileSystemInfo class.
Problem:
While this service is running, I am unable to uninstall some programs for example (Microsoft Security Essentials). I have a feeling that these service is HANGING ON TO THE RESOURCES of the files marked for deletion because I can only uninstall those programs if only this service is running.
My Question is how can I GET THE PROPERTIES OF THE FILE (as specified above) in an ALTERNATIVE & efficient way without hanging on to the resources of the file ?
Here is my code using the FileSystemInfo
public void OnCreate/OnRenamed(object source, FileSystemEventArgs e)
{ FileInfo file = new FileInfo(e.FullPath);
String output = "<Event><TimeStamp>" + currentTime + "</TimeStamp>";
output += "<Name>" + action + "</Name>";
output += "<Properties><FileName>" + file.Name + "</FileName>";
output += "<FullPath>" + file.FullName + "</FullPath>";
output += "<FileSize>" + file.Length + "</FileSize>";
output += "<CreationTime>" + String.Format("{0:yyyyMMdd-HHmmss.fff}", file.CreationTime) + "</CreationTime>";
output += "<LastAccess>" + String.Format("{0:yyyyMMdd-HHmmss.fff}", file.LastAccessTime) + "</LastAccess>";
output += "<LastWriteTime>" + String.Format("{0:yyyyMMdd-HHmmss.fff}", file.LastWriteTime = DateTime.Now) + "</LastWriteTime></Properties></Event>";
}
Sincerely,
Derek
Using FileSystemInfo will not normally 'hang on' to these files. You have to first figure out what exactly is causing other programs to stuck during uninstallation. Use ProcessMonitor to see what files are being accessed during uninstallation. The tool is pretty self explanatory, you need to filter on file system activity. Read this or google around.
Try to experiment by taking out one thing at a time. I assume these programs get uninstalled successfully when your service is not running. This proves that it is indeed your service that is causing issues. First comment your FileSystemInfo code. See if the problem goes away. Then comment out FileSystemWatcher and see if it helps.
Update: looks like this is offending line:
file.LastWriteTime = DateTime.Now
Try to comment this assignement and see if it solves the problem:
file.LastWriteTime /* = DateTime.Now */
Was this a typo or you really need to write LastWriteTime?
What you could do is every interval check for LastAccessTime and LastWriteTime and do some quick math based on the interval and you can determine if the file was last accessed or modified within the interval time. If it was, do what you have to do. Just an idea...

Categories

Resources