Error log with a counter - c#

I have a c# project and a log file with errors. I want to give all errors on a new log file out with a counter if there are some errors twice or more. I used the command:
bool alreadyExist = fails.Contains(line);
This works really good, but I want also a counter, to show how many times I have the same line in a log file.

Using Regex:
Regex.Matches(fails, line).Count

Assuming fails is an IEnumerable<string> where each element is a log file line, this should work:
int count = fails.Count((x) => x.Equals(line));

Related

Log tracepoint messages to a text file

I've added a conditional breakpoint in a C# project along with an "Action" that writes a message to the console. Basically, when you check "Actions", you are only provided an option to "Log a message to the Output Window" (this is VS 2015).
What if I wanted to also log that message to a text file? I've been reading about trace listeners but can't figure out how to hook one up to my tracepoint.
Tracepoints can only be used while debugging - since they are kept track of by the Visual Studio IDE debugger. I actually tried to set up a listener to write out the trace to a log file, but it looks like this functionality is not supported for tracepoints. But, it does work for the Trace class.
So, it looks like you are stuck with the output window while debugging. You can always copy and paste the contents of the output window to a file while debugging. If your intent was to use it for release code, then you should either use custom logging or the Trace class.
By default, the trace class writes to the output window. But, the default listener may be modified to also log Trace.WriteLine statements to a log file as well. For example:
using System.Diagnostics;
// Set up the log file to be the folder where the program is run from, with the name Trace.log.
DefaultTraceListener DefListener = (DefaultTraceListener)Trace.Listeners[0];
DefListener.LogFileName = AppDomain.CurrentDomain.BaseDirectory + "Trace.log";
// Write out the value of Count within the loop to the log file.
for (int Loop = 0; Loop < 5; Loop++)
{
Count++;
Trace.WriteLine($"Count = {Count}");
}
DefListener.Flush();
The contents of the log file will then contain:
Count = 1
Count = 2
Count = 3
Count = 4
Count = 5
The above code works for both release and debug builds.

Creating previously deleted source in different event log doesnt work

I have been fighting with the Windows Event log for lots of hours with inconsistent behaviour during test of the log4net EventLogAppender and I realized, that the log4net code worked, but my windows event log was the one being unreasonable.
System
OS: Windows 8.1
C#: .Net 4.5, built to x64
Creating the error case
C#: Create Source1 in TestLog1
C#: Write to the log (Works)
Powershell: Removing the log using powershell
C# Create Source1 in TestLog2 (Different log)
C# Write to the log <= This shows no log entries in TestLog2!
I have made a complete step-by-step guide to recreate the problem:
1: Create a new source in a new log and write to it
Code executed:
EventLog.CreateEventSource(source: "TestSource1", logName: "TestLog1");
EventLog myLog = new EventLog();
myLog.Source = "TestSource1";
myLog.WriteEntry("This is a message");
List logs using powershell-command:
Get-EventLog -LogName *
This will correctly list all logs, including TestLog1 containing 1 log entry.
I can also get the log entries by using this powershell command:
GetEventLog -LogName "TestLog1"
This shows me the single log message in the log.
2: Delete the event log using powershell
Powershell command:
Remove-EventLog -LogName "TestLog1"
Listing all logs now shows, that the log has actually been deleted. Powershell command again:
Get-EventLog -LogName *
3: Create the source again, but in another log this time
Code executed:
EventLog.CreateEventSource(source: "TestSource1", logName: "TestLog2"); // New log name
EventLog myLog = new EventLog();
myLog.Source = "TestSource1";
myLog.WriteEntry("This is a message");
Result:
The log appears in powershell when listing all logs
The log does not contain any entry
Using Get-EventLog "TestLog2" throws and exception even though it appears in the log-list
Deleting the log in powershell using remove-eventlog -logName "TestLog2" somehow still works.
It seems that in some cases, the logs seems to exist, but in others it doesnt.
A: Is this a known bug or what is wrong with my scenario?
B: How can I clean up my existing mess if sources somehow still exist pointing at the old log? (If thats the case, that is)
EDIT: I even tried the following C# code to delete the source first and then the log, but the result is the same:
var source = "TestSource6";
var logName1 = "Testlog5";
var logName2 = "Testlog6";
EventLog.CreateEventSource(source: source, logName: logName1);
new EventLog() { Source = source }.WriteEntry("This is a message in log " + logName1);
EventLog.DeleteEventSource(source:source);
EventLog.Delete(logName:logName1);
EventLog.CreateEventSource(source: source, logName: logName2);
new EventLog() { Source = source }.WriteEntry("This is a message" + logName2);
Unfortunately you can't re-register an event source "back to back". It's one of the (many) reasons installers often ask to restart the computer.
From MSDN:
If a source has already been mapped to a log and you remap it to a new log, you must restart the computer for the changes to take effect.
EventLog.CreateEventSource Method (String, String)
For fixing the issue, I would recommend not deleting the event source unless the product is uninstalled. Just stop using Log1 and start using Log2, without deleting and recreating. When you go to use any log, you could use something similar to this:
if (!EventLog.SourceExists(source, log))
{
EventLog.CreateSource(source, log)
}
And simply leave the source where it is, until you uninstall the product. If you're using InstallShield, it should automatically detect a restart is required and ask the user to do so.

Batch load files in AutoCAD

I'm running into problems writing an application to batch load and export files in AutoCAD using a C#. I've received numerous errors listed below whenever I point to a folder full of .dxf files. I've been able to narrow the problem down to the point where I know it's only breaking on load. Sometimes it loads fine, others it will only load 3-4 files, and the rest of the time it will simply throw an error. The errors I'm seeing include but are not limited to FaultExecutionEngineError, NullExceptionError, IndexOutOfRange error, and the wonderful FATAL EXCEPTION error, which causes Autocad to crash as well.
Here is my code:
public class MyCommands
{
string folderPath = #"C:\Users\kdhyne\Desktop\New folder\";
// Modal Command with localized name
[CommandMethod("FileCycle", CommandFlags.Session)]
public void MyCommand() // This method can have any name
{
var acDocManager = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;
string[] filesInDirectory;
Document acDoc = null;
filesInDirectory = Directory.GetFiles(folderPath, "*.dxf", SearchOption.TopDirectoryOnly);
foreach (string someFile in filesInDirectory)
{
acDoc = acDocManager.Open(someFile);
}
}
}
I've stripped this down as far as I can think. Hopefully someone can help. Thank you for reading.
Do a release build before opening it in AutoCAD and it seems to work fine! Apparently it wasn't compiling all the libraries into the debug build.

Standard way to keep debug lines in the program

I would like to add some debug lines to my program. Once after executing statements it will record the current status to a file.
I have done that in following way.
public int? DoWork(int x, int y)
{
Log.Write("Received inputs. X an Y values are:"+x+","+y);
bool result = ChekData(x);
if (!result)
{
Log.Write("First input is not valid");
return null;
}
result = ChekData(y);
if (!result)
{
Log.Write("Second input is not valid");
return null;
}
Log.Write("Valid input found");
....
....
}
I feel this is not the standard wa to do this. Keeping text like this in the code. After searching I found using Resource file I can save these messages like name value pair.
But I have no idea about the standard of that. Please advise me.
Basicaly for the loging I am using Log4Net
This is pretty normal way of doing logging.
Using resource files for logging generally does not make sense because:
it moves descriptive message away from the place it most useful - inline code
logs most commonly used by original developers, so getting logs in Japanese (if log resource strings are properly localized) is rarely useful for English speaking developers and vise versa.
avoiding localization of some strings (one that are used for logging) may be inconvenient, localizing them is not free...
If it is only for debug purpose i would do the following:
Set appropriate debuglevels. The debug version should then be build using a level to show all messages. The release build normally don't need debug outputs. Therefore disable the message level for release output.
For distinction if you are in release build or debug build you can use the following 2 things:
#if DEBUG
// enable all tracing
#endif
or if you also want that your realease build brings messages if a Debugger is Attached
if(System.Diagnostics.Debugger.IsAttached)
{
// Someone has attached a debugger, so give more output
}
You can also wrap the logcalls if you want with a method which justs checks for debug/attached debugger..

Add to List<string> from text file

I have a List<string> that I would like to populate via a text file that is set as a project resource. I have looked all over on a way to do this but haven't yet found one that doesn't cause my program to crash.
If I manually populate the list...
_names.Add("Sam");
_names.Add("John");
_names.Add("Mike");
...everything works. My text file has each name on a separate line, no commas or anything. When I try to read in the names, the program crashes, no matter which route I take. This is the most recent way I've tried, though there are many others:
using (var reader = new StreamReader(Properties.Resources.sampleNamesMale))
{
string line;
while ((line = reader.ReadLine()) != null)
{
_names.Add(line);
}
}
Also, I can't isolate the reason for the crash because every time it does, the error just mentions ViewModelLocator, which is entirely irrelevant to this issue.
Does anybody have any ideas about how to fix this? I would certainly appreciate any advice.
Update: Try-catch yields no results. This is the error I get:
XamlParseException occurred - 'The invocation of the constructor on type 'AoW.ViewModels.ViewModelLocator' that matches the specified binding constraints threw an exception.' Line number '13' and line position '10'.
It points at InitializeComponent() in my main window's constructor.
Update 2: The real exception is this:
"ArgumentException occurred - Illegal characters in path." It points at the using (var reader.... line.
Use a StringReader instead of a StreamReader:
using (var reader = new StringReader(Properties.Resources.sampleNamesMale))
You are getting that error because StreamReader(string) expects a file path. If you are providing the actual text in Properties.Resources.sampleNamesMale, you have to use a StringReader.
The only way you could get the exception:
ArgumentException occurred - Illegal characters in path.
is if the path returned by Properties.Resources.sampleNamesMale was literally invalid:
using (var reader = new StreamReader(Properties.Resources.sampleNamesMale))
After second update the answer is very easy: display in debugger what is a path to your file and make it correct. Probably it contains spaces in the end or not escaped \

Categories

Resources