Parse IP addresses out of a web server log file
I had written a quick script off the top of my head, but my astute reader reminded me of the fully-featured LogParser tool that can not only extract IP addresses but can also pull out a whole host of information from your log files:
This is horribly inefficient for large files or large amount of files.
It would be better to do this on a line by line basis.
@Ayende,
Perhaps, but it works great for 10-20 files. š Just enough to find out what IP addresses have accessed the server in the past few days.
You asked for it. š
require āsetā
require āppā
results = SortedSet.new
Dir[ā*.logā].each do |path|
File.read(path).scan(
/b(d{1,3}.d{1,3}.d{1,3}.d{1,3})b/
).flatten.each { |ip| results << ip }
end
pp results
It took me 2 minutes to write this (I'm slow š ). Not that you took any longer. I've just been thinking lately how it feels like I'm at the point where I can constantly throw away little solutions like this and not get wrapped up in reusability for a utility because they're one of the few things I can (almost) write faster in my head than I can type.
That level of proficiency or approach to a problem doesn't get much press in programming circles it seems. Then again, not much more to say, so that's probably just because it's not a very interesting topic. Just thinking out loud here. š
Walk, donāt run, to http://www.logparser.com, and query your logs like you would if they were SQL tables ⦠š
Log parser is the way to go⦠especially when you are talking about large log files.
http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en
1 word: PowerShell! š
Jeffrey ā Ayendeās right here. The performance implications of the following lines are really terrible:
string text = āā;
ā¦
foreach (var filePath in filePaths) {
text += File.ReadAllText(filePath);
}
Youāre allocating:
1.) A string to hold the entire contents of 1 text file
2.) Another string that holds the entire contents read up to this point PLUS the data from step #1
3.) And youāre repeating this for every log file
Like he said, you could solve this by processing a file at a time, line-by-line, but if you donāt want to do that, you could improve things tremendously by using a StringBuild that you append to.
I canāt believe you havenāt heard of āxā. There are what? 600 different things that could have worked? You did one that you know well and wrote quickly, thatās what works well. There a couple things I donāt agree with.
1. loading all of the files into a single combined text string. I would have opened one file, processed the matches then moved on to the next file.
2. Writing and running this as a unit test. The test framework brings nothing to your solution. You arenāt using a setup or any assertions. You have a console application that you use NUnit to run. Iād have just written it as a console application.
I probably would have also output the results to a file instead of just the console window, but thatās a very minor change.
Iām just left wondering what your intention with this post wasā¦
You knew there were better tools and method out there to do the job, and you knew people would call them out. So that rules out the āproviding a solution for others to followā motive.
But then you seem a bit defensive when people suggest alternatives, so that rules out the āinformation gatheringā motive.