mike_at_somedude_dot_com
asked on
IIS 6 - View Each Site's Bandwidth Usage
I need to find a program that will allow me to view the bandwidth useage for each site setup in IIS individually.
Here is the reason I need this... we have a dedicated server and are allowed so much bandwidth per month... One customer went over their alotted bandwidth and made our bill go up. We want to find a way to see how much bandwidth each site is using so that we can bill them accordingly. I don't care if it analyzes log files or uses some other method to find the bandwidth used, just as long as it can accurately display the total badwidth used for each site.
The log files are all in different directories (i.e. C:\site1\logs, C:\site2\logs, C:\site3\logs, etc.) We are not moving the log files into a common directory so please don't even suggest it something that would require this course of action.
A free solution would be best. I don't want something that is going to cost me 200 bucks and I don't even really know if it's what I want or not.
Here is the reason I need this... we have a dedicated server and are allowed so much bandwidth per month... One customer went over their alotted bandwidth and made our bill go up. We want to find a way to see how much bandwidth each site is using so that we can bill them accordingly. I don't care if it analyzes log files or uses some other method to find the bandwidth used, just as long as it can accurately display the total badwidth used for each site.
The log files are all in different directories (i.e. C:\site1\logs, C:\site2\logs, C:\site3\logs, etc.) We are not moving the log files into a common directory so please don't even suggest it something that would require this course of action.
A free solution would be best. I don't want something that is going to cost me 200 bucks and I don't even really know if it's what I want or not.
BTW - there is a free trial for LogFileManager, but it costs $39.95 to register and keep.
It's pretty easy to script something that picks up the total for a log file. I wrote some to do that for my own servers in Perl, but VBScript is just as capable of doing it.
Really it just depends on how you perform logging. Daily log files like ex050420.log? And I assume you log bytes-sc / bytes-cs?
Different directories are no problem, even preferable since it gives a nice easy way to figure out what is being read in.
Beyond that... how often / what period do you want to pull bandwidth for and how do you want it reported?
And is this the kind of solution you'd like to persue?
Just for the sake of a sample, this section of perl script is at the core of my own script. It does the bit that matters, counts the usage from a single file (file name is passed into the sub):
sub Logs_Parse
# This function processes a single log file pulling out the sc-bytes field.
# Because not much in the way of data-validation is done this will pull up a lot of warnings with debugging on (use
# warnings and use diagnostics).
# All lines beginning with # are ignored except the #Fields line which is used to determine the position of sc-bytes
{
my $funcLogFile = shift(@_);
my $funcFieldCount = 0;
my $funcFieldPosition = 0;
my $funcFileTotal = 0;
my $funcByteCurrent = 0;
my $funcFieldFound = "FALSE";
eval {
open (LOGFILE, "<$funcLogFile") or die "Error opening File - $funcLogFile";
};
if ($@)
{
print "$@\n";
}
else
{
while (my $funcLine = <LOGFILE>)
{
chomp($funcLine);
my @funcLineArray = split(/ /, $funcLine);
if ($funcLineArray[0] =~ m/\#/)
{
if ($funcLineArray[0] eq '#Fields:')
{
foreach my $funcField (@funcLineArray)
{
if ($funcField eq "sc-bytes")
{
# Because the main file doesn't have an extra field in front called #Fields:...
$funcFieldPosition = $funcFieldCount - 1;
$funcFieldFound = "TRUE";
}
$funcFieldCount = ++$funcFieldCount;
}
}
}
if ($funcFieldFound eq "TRUE")
{
$funcByteCurrent = $funcLineArray[$funcFieldP
$funcFileTotal = $funcFileTotal + $funcByteCurrent;
}
}
print "$funcFileTotal\n";
close LOGFILE;
return $funcFileTotal;
}
}
In my case this all adds up to create a monthly total. The rest of the code wraps around figuring out how to get the file names in the first place, how to do it for lots of different log directories and how to report it.
ASKER
humeniuk: I don't want a control panel on the server. We make sites in coldfusion and then host them on our servers after we are done. Our users do not know how to program or anything, therefore we don't need FTP or any sort of control panel or anything, it's just plain old hosting. The log file tool you suggested looks like it requires all log files to be in the same directory, as I stated before, this is not possible.
Chris-Dent: I don't know anything about perl and we don't allow scripts to be run from the server other than coldfusion. It is a dedicated server and we can connect remotely so I was hoping for some sort of program or something that we could install and it would only be accesible to people remotely connected.
Chris-Dent: I don't know anything about perl and we don't allow scripts to be run from the server other than coldfusion. It is a dedicated server and we can connect remotely so I was hoping for some sort of program or something that we could install and it would only be accesible to people remotely connected.
Can the server run vbscript or ASP at all? That normally doesn't require any installation.
ASKER
Yeah ASP is enabled
The bandwidth monitoring script can be run as part of an ASP page (I have a vbscript log file parser as well as the perl version), or run as a scheduled task on the server.
It just depends on how you want to report bandwidth (on demand / scheduled / monthly / weekly etc etc) and what the filenames of the log files are.
Let me know that and I'll dump you some code to try, you can see if you like it and go from there.
Chris
ASKER
The filenames are the default IIS names (exyymmdd.log). Monthly would probably be the best reporting period.
Okay this is a basic version (works but doesn't produce pretty output). It's quite long, but it produces the total of last months logs (total for March). The logs it picks and totals can quite easily be altered. The main point is to get it producing a figure in the first place.
One thing you will need to alter, it requires the relative path from the website root to the logs for strLogFolder. It's commented, but let me know if you have any problems.
<html>
<head>
<title>
<%
Dim strDomainName
strDomainName = Request.ServerVariables("H
Response.Write("Bandwidth Report - " & strDomainName)
%>
</title>
</head>
<body>
<%
' A very basic HTML wrapper for this
Set objFileSystem = CreateObject("Scripting.Fi
strServerPath = Request.ServerVariables("A
' For this version to work you need to give the relative path from the www root to the log files.
' The user running this script must have access rights to the logs or it won't work.
strLogFolder = strServerPath & "<Log File Path from www Root>"
' e.g.
' strLogFolder = strServerPath & "\LogFiles"
Function FileTotal(strLogName)
' A function that returns the number of bytes from a particular log file
intFieldCount = 0
intFieldPosition = 0
intFileTotal = 0
intByteCurrent = 0
booFieldFound = "FALSE"
' Clear out any previous errors and initialize error handling
Err.Clear
On Error Resume Next
Set objFile = objFileSystem.GetFile(strL
Set objTextStream = objFile.OpenAsTextStream(1
If (Err <> 0) Then
Else
Do
booIgnore = "FALSE"
strLine = objTextStream.ReadLine()
arrLine = split(strLine, " ")
' Get the field positions
If (arrLine(0) = "#Fields:") Then
For Each strElement in arrLine
If (strElement = "sc-bytes") Then
intFieldPosition = intFieldCount - 1
booFieldFound = "TRUE"
End If
intFieldCount = intFieldCount + 1
Next
End If
If (booFieldFound = "TRUE") Then
intByteCurrent = arrLine(intFieldPosition)
intFileTotal = intFileTotal + intByteCurrent
End If
Loop while not objTextStream.AtEndOfStrea
objFile.Close
End If
FileTotal = intFileTotal
End Function
Function FileName(strMonth, strYear)
' Creates the partial log filename from the Month and Year
If (strMonth < 10) Then
strMonth = "0" & strMonth
End If
strYear = Right(strYear, 2)
strPartialName = "ex" & strYear & strMonth
FileName = strPartialName
End Function
'
' Main Section
'
' Connect to the log folder to get the full path
Set objFolder = objFileSystem.GetFolder(st
' Attempt to Connect to the W3SVC folder
For Each objSubFolder in objFolder.SubFolders
If ((InStr(objSubFolder.Name,
strLogFolder = objSubFolder.Path
booConnected = "TRUE"
End If
Next
Set objFolder = Nothing
' Start out by running it for last month...
strMonth = DatePart("m",Date())
strYear = DatePart("yyyy",Date())
' Set it up to process logs from last month
If (strMonth = 1) Then
strYear = strYear - 1
strMonth = 12
Else
strMonth = strMonth - 1
End If
strPartialName = FileName(strMonth, strYear)
Set objFolder = objFileSystem.GetFolder(st
int LogsTotal = 0
For Each objFile in objFolder.Files
If (InStr(objFile.Name, strPartialName) <> 0) Then
strLogFile = objFile.Path
intTotal = FileTotal(strLogFile)
intLogsTotal = intLogsTotal + intTotal
End If
Next
Response.Write("Total Bytes Used in Logs: " & intLogsTotal)
%>
</body>
</html>
ASKER
Does this only work for one folder? In my initial question, I stated that the log files are in a bunch of different folders (i.e. wwwroot/client1/logs, wwwroot/client2/logs, etc.). There are at least 50-60 clients so it would be very inconvenient to have to change the variable, run the script, change the variable, run the script, and so on for each client.
It's a sample only, it runs for one particular site, but that can be any particular site.
I can easily change to just process for directories rather than sites.
Are they all like:
c:\site1.com\logs
c:\site2.com\logs
Or does the location of logs vary between sites?
Give me a few minutes and I'll post another version.
ASKER
Well this is how it works. We have all of the sites on a second drive, seperate from the boot drive. Each site is in a folder inside the sites folder so we have it like this...
D:\sites\acs\
D:\sites\adr\
etc.
Each folder has a folder named logs in it:
D:\sites\acs\logs\
D:\sites\adr\logs\
etc.
Inside of each of the log folders is one single folder, named by windows, which includes the actual logs... Here is an example:
D:\sites\acs\logs\W3SVC935 79\
D:\sites\adr\logs\W3SVC539 76\
etc.
The actual log files are inside these folder so a sample path to a log would be:
D:\sites\acs\logs\W3SVC935 79\ex05042 1.log
D:\sites\acs\
D:\sites\adr\
etc.
Each folder has a folder named logs in it:
D:\sites\acs\logs\
D:\sites\adr\logs\
etc.
Inside of each of the log folders is one single folder, named by windows, which includes the actual logs... Here is an example:
D:\sites\acs\logs\W3SVC935
D:\sites\adr\logs\W3SVC539
etc.
The actual log files are inside these folder so a sample path to a log would be:
D:\sites\acs\logs\W3SVC935
Perfect thanks... won't be a sec.
One thing to beware of for this... if it has to do a lot of processing it might exceed the script timeout on the server. If you can run it as a scheduled task on the server it can be modified to dump the output to a text file. Let me know if you'd like to do that.
As before it still only processes the log files for last month.
<html>
<head>
<title>
<%
Dim strDomainName
strDomainName = Request.ServerVariables("H
Response.Write("Bandwidth Report")
%>
</title>
</head>
<body>
<%
' A very basic HTML wrapper for this
Set objFileSystem = CreateObject("Scripting.Fi
strSiteFolder = "d:\sites"
' For this version to work you need to give the relative path from the www root to the log files.
' The user running this script must have access rights to the logs or it won't work.
strLogPath = "\logs"
' e.g.
' strLogPath = "\logs"
' This will combine to create d:\sites\<site folder>\logs
'
' Functions
'
Function FileTotal(strLogName)
' A function that returns the number of bytes from a particular log file
intFieldCount = 0
intFieldPosition = 0
intFileTotal = 0
intByteCurrent = 0
booFieldFound = "FALSE"
' Clear out any previous errors and initialize error handling
Err.Clear
On Error Resume Next
Set objFile = objFileSystem.GetFile(strL
Set objTextStream = objFile.OpenAsTextStream(1
If (Err = 0) Then
Do
booIgnore = "FALSE"
strLine = objTextStream.ReadLine()
arrLine = split(strLine, " ")
' Get the field positions
If (arrLine(0) = "#Fields:") Then
For Each strElement in arrLine
If (strElement = "sc-bytes") Then
intFieldPosition = intFieldCount - 1
booFieldFound = "TRUE"
End If
intFieldCount = intFieldCount + 1
Next
End If
If (booFieldFound = "TRUE") Then
intByteCurrent = arrLine(intFieldPosition)
intFileTotal = intFileTotal + intByteCurrent
End If
Loop while not objTextStream.AtEndOfStrea
objFile.Close
End If
FileTotal = intFileTotal
End Function
Function FileName(strMonth, strYear)
' Creates the partial log filename from the Month and Year
If (strMonth < 10) Then
strMonth = "0" & strMonth
End If
strYear = Right(strYear, 2)
strPartialName = "ex" & strYear & strMonth
FileName = strPartialName
End Function
'
' Main Section
'
' Start out by running it for last month...
strMonth = DatePart("m",Date())
strYear = DatePart("yyyy",Date())
' Set it up to process logs from last month
If (strMonth = 1) Then
strYear = strYear - 1
strMonth = 12
Else
strMonth = strMonth - 1
End If
strPartialName = FileName(strMonth, strYear)
' Connect to the log folder to get the full path
Set objSiteFolder = objFileSystem.GetFolder(st
For Each objSite in objSiteFolder.SubFolders
' Make sure the logs folder exists first
strLogFolder = objSite.Path & strLogPath
If (objFileSystem.FolderExist
Set objFolder = objFileSystem.GetFolder(st
' Attempt to Connect to the W3SVC folder
For Each objSubFolder in objFolder.SubFolders
If ((InStr(objSubFolder.Name,
strLogFolder = objSubFolder.Path
booConnected = "TRUE"
End If
Next
Set objFolder = Nothing
Set objFolder = objFileSystem.GetFolder(st
int LogsTotal = 0
For Each objFile in objFolder.Files
If (InStr(objFile.Name, strPartialName) <> 0) Then
strLogFile = objFile.Path
intTotal = FileTotal(strLogFile)
intLogsTotal = intLogsTotal + intTotal
End If
Next
Response.Write("Total Bytes Used in Logs for " & objSite.Name & ": " & intLogsTotal & "<br />")
End If
Next
%>
</body>
</html>
ASKER
Not working, it just says 0 for the first 15 or so sites, and then throws a timeout error.
Total Bytes Used in Logs for acs: 0
Total Bytes Used in Logs for adr: 0
Total Bytes Used in Logs for AdvancedAudio: 0
Total Bytes Used in Logs for annabellegutman: 0
Total Bytes Used in Logs for atomiccomputerservices: 0
Total Bytes Used in Logs for Belayer: 0
Total Bytes Used in Logs for BigTallShort: 0
Total Bytes Used in Logs for buggerhugger: 0
Total Bytes Used in Logs for buyaudiogear: 0
Total Bytes Used in Logs for CentralChristian2: 0
Total Bytes Used in Logs for CentralChristianBeta: 0
Total Bytes Used in Logs for checkoutaisle: 0
Total Bytes Used in Logs for CreativeAudioServices: 0
Total Bytes Used in Logs for DewaldHealthCare: 0
Total Bytes Used in Logs for dobsonranchinn: 0
Total Bytes Used in Logs for elpradogalleries: 0
Total Bytes Used in Logs for escomconsulting: 0
Total Bytes Used in Logs for GetAwayStakes: 0
Active Server Pages error 'ASP 0113'
Script timed out
/loganalysis/index.asp
The maximum amount of time for a script to execute was exceeded. You can change this limit by specifying a new value for the property Server.ScriptTimeout or by changing the value in the IIS administration tools.
Total Bytes Used in Logs for acs: 0
Total Bytes Used in Logs for adr: 0
Total Bytes Used in Logs for AdvancedAudio: 0
Total Bytes Used in Logs for annabellegutman: 0
Total Bytes Used in Logs for atomiccomputerservices: 0
Total Bytes Used in Logs for Belayer: 0
Total Bytes Used in Logs for BigTallShort: 0
Total Bytes Used in Logs for buggerhugger: 0
Total Bytes Used in Logs for buyaudiogear: 0
Total Bytes Used in Logs for CentralChristian2: 0
Total Bytes Used in Logs for CentralChristianBeta: 0
Total Bytes Used in Logs for checkoutaisle: 0
Total Bytes Used in Logs for CreativeAudioServices: 0
Total Bytes Used in Logs for DewaldHealthCare: 0
Total Bytes Used in Logs for dobsonranchinn: 0
Total Bytes Used in Logs for elpradogalleries: 0
Total Bytes Used in Logs for escomconsulting: 0
Total Bytes Used in Logs for GetAwayStakes: 0
Active Server Pages error 'ASP 0113'
Script timed out
/loganalysis/index.asp
The maximum amount of time for a script to execute was exceeded. You can change this limit by specifying a new value for the property Server.ScriptTimeout or by changing the value in the IIS administration tools.
Could you add:
<% Server.ScriptTimeout = 900 %>
To the beginning, that gives it 15 minutes to run, shouldn't take that long.
Also need to add a few bits to the code to see where it's breaking if that's okay...
Can you change the end section to match this:
Set objFolder = objFileSystem.GetFolder(st
int LogsTotal = 0
Response.Write(objSite.Nam
For Each objFile in objFolder.Files
If (InStr(objFile.Name, strPartialName) <> 0) Then
strLogFile = objFile.Path
Response.Write(objFile.Pat
intTotal = FileTotal(strLogFile)
intLogsTotal = intLogsTotal + intTotal
End If
Next
Response.Write("Total Bytes Used in Logs for " & objSite.Name & ": " & intLogsTotal & "<br />")
End If
Next
%>
</body>
</html>
A space has managed to lodge itself in an inconvenient place above...
int LogsTotal = 0
Should be
intLogsTotal = 0
Or it'll add all the totals together and the last one on the list will have a really massive amount of bandwidth usage.
ASKER
Same thing, 0 bytes for everything. I'm just going to copy and paste the output for the first directory since it would be way too much if I were to copy and paste it all...
acs: D:\sites\acs\logs\W3SVC669 916 - D:\sites\acs\logs\W3SVC669 916
D:\sites\acs\logs\W3SVC669 916\ex0503 01.log
D:\sites\acs\logs\W3SVC669 916\ex0503 02.log
D:\sites\acs\logs\W3SVC669 916\ex0503 03.log
D:\sites\acs\logs\W3SVC669 916\ex0503 04.log
D:\sites\acs\logs\W3SVC669 916\ex0503 05.log
D:\sites\acs\logs\W3SVC669 916\ex0503 06.log
D:\sites\acs\logs\W3SVC669 916\ex0503 07.log
D:\sites\acs\logs\W3SVC669 916\ex0503 08.log
D:\sites\acs\logs\W3SVC669 916\ex0503 09.log
D:\sites\acs\logs\W3SVC669 916\ex0503 10.log
D:\sites\acs\logs\W3SVC669 916\ex0503 11.log
D:\sites\acs\logs\W3SVC669 916\ex0503 12.log
D:\sites\acs\logs\W3SVC669 916\ex0503 13.log
D:\sites\acs\logs\W3SVC669 916\ex0503 14.log
D:\sites\acs\logs\W3SVC669 916\ex0503 15.log
D:\sites\acs\logs\W3SVC669 916\ex0503 16.log
D:\sites\acs\logs\W3SVC669 916\ex0503 17.log
D:\sites\acs\logs\W3SVC669 916\ex0503 18.log
D:\sites\acs\logs\W3SVC669 916\ex0503 19.log
D:\sites\acs\logs\W3SVC669 916\ex0503 20.log
D:\sites\acs\logs\W3SVC669 916\ex0503 21.log
D:\sites\acs\logs\W3SVC669 916\ex0503 22.log
D:\sites\acs\logs\W3SVC669 916\ex0503 23.log
D:\sites\acs\logs\W3SVC669 916\ex0503 24.log
D:\sites\acs\logs\W3SVC669 916\ex0503 25.log
D:\sites\acs\logs\W3SVC669 916\ex0503 26.log
D:\sites\acs\logs\W3SVC669 916\ex0503 27.log
D:\sites\acs\logs\W3SVC669 916\ex0503 28.log
D:\sites\acs\logs\W3SVC669 916\ex0503 29.log
D:\sites\acs\logs\W3SVC669 916\ex0503 30.log
D:\sites\acs\logs\W3SVC669 916\ex0503 31.log
Total Bytes Used in Logs for acs: 0
acs: D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
Total Bytes Used in Logs for acs: 0
No problem.. that's plenty.
Could you open one of the log files and post the #Fields line please? The parser should auto-adjust to get the position of sc-bytes, but it requires the #Fields line. I just need to check nothing will throw up a problem there.
Basically, the problem is either with the file parser function or the sites just aren't logging the sc-bytes in the log file options.
And the two response write statements for debugging can be removed from the code above:
Response.Write(objSite.Nam
Response.Write(objFile.Pat
Which should make the output a bit more practical.
ASKER
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status sc-substatus sc-win32-status sc-bytes cs-bytes
We'll just go with me breaking the function with too much playing then ;)
Try this one please:
Function FileTotal(strLogName)
' A function that returns the number of bytes from a particular log file
intFieldCount = 0
intFieldPosition = 0
intFileTotal = 0
intByteCurrent = 0
booFieldFound = "FALSE"
' Clear out any previous errors and initialize error handling
Set objFile = objFileSystem.GetFile(strL
Set objTextStream = objFile.OpenAsTextStream(1
Do
booIgnore = "FALSE"
strLine = objTextStream.ReadLine()
arrLine = split(strLine, " ")
' Get the field positions
If (arrLine(0) = "#Fields:") Then
For Each strElement in arrLine
If (strElement = "sc-bytes") Then
intFieldPosition = intFieldCount - 1
booFieldFound = "TRUE"
End If
intFieldCount = intFieldCount + 1
Next
End If
' Ignore other lines starting with #
If (Left(arrLine(0), 1) = "#") Then
booIgnore = "TRUE"
End If
' Count up the total
If ((booFieldFound = "TRUE") and (booIgnore = "FALSE")) Then
intByteCurrent = arrLine(intFieldPosition)
intFileTotal = intFileTotal + intByteCurrent
End If
Loop while not objTextStream.AtEndOfStrea
FileTotal = intFileTotal
End Function
ASKER
Looks like the same as last time...
acs: D:\sites\acs\logs\W3SVC669 916 - D:\sites\acs\logs\W3SVC669 916
D:\sites\acs\logs\W3SVC669 916\ex0503 01.log
D:\sites\acs\logs\W3SVC669 916\ex0503 02.log
D:\sites\acs\logs\W3SVC669 916\ex0503 03.log
D:\sites\acs\logs\W3SVC669 916\ex0503 04.log
D:\sites\acs\logs\W3SVC669 916\ex0503 05.log
D:\sites\acs\logs\W3SVC669 916\ex0503 06.log
D:\sites\acs\logs\W3SVC669 916\ex0503 07.log
D:\sites\acs\logs\W3SVC669 916\ex0503 08.log
D:\sites\acs\logs\W3SVC669 916\ex0503 09.log
D:\sites\acs\logs\W3SVC669 916\ex0503 10.log
D:\sites\acs\logs\W3SVC669 916\ex0503 11.log
D:\sites\acs\logs\W3SVC669 916\ex0503 12.log
D:\sites\acs\logs\W3SVC669 916\ex0503 13.log
D:\sites\acs\logs\W3SVC669 916\ex0503 14.log
D:\sites\acs\logs\W3SVC669 916\ex0503 15.log
D:\sites\acs\logs\W3SVC669 916\ex0503 16.log
D:\sites\acs\logs\W3SVC669 916\ex0503 17.log
D:\sites\acs\logs\W3SVC669 916\ex0503 18.log
D:\sites\acs\logs\W3SVC669 916\ex0503 19.log
D:\sites\acs\logs\W3SVC669 916\ex0503 20.log
D:\sites\acs\logs\W3SVC669 916\ex0503 21.log
D:\sites\acs\logs\W3SVC669 916\ex0503 22.log
D:\sites\acs\logs\W3SVC669 916\ex0503 23.log
D:\sites\acs\logs\W3SVC669 916\ex0503 24.log
D:\sites\acs\logs\W3SVC669 916\ex0503 25.log
D:\sites\acs\logs\W3SVC669 916\ex0503 26.log
D:\sites\acs\logs\W3SVC669 916\ex0503 27.log
D:\sites\acs\logs\W3SVC669 916\ex0503 28.log
D:\sites\acs\logs\W3SVC669 916\ex0503 29.log
D:\sites\acs\logs\W3SVC669 916\ex0503 30.log
D:\sites\acs\logs\W3SVC669 916\ex0503 31.log
Total Bytes Used in Logs for acs: 0
acs: D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
D:\sites\acs\logs\W3SVC669
Total Bytes Used in Logs for acs: 0
How odd.. I can't get it to break on mine..
Could you post a couple of lines of a log file and I'll rerun it to check it's pulling the data out.
Oh and the path and filenames it's producing are correct?
Okay sorry about this... probably due to some mistakes I had...
So I rewrote some of the error handling and made sure it worked for my site structure - which is pretty much identical to your own except logs is another directory down.
Let me know if it still produces 0 please.
<html>
<% Server.ScriptTimeout = 900 %>
<head>
<title>
<%
Dim strDomainName
strDomainName = Request.ServerVariables("H
Response.Write("Bandwidth Report")
%>
</title>
</head>
<body>
<%
' A very basic HTML wrapper for this
Set objFileSystem = CreateObject("Scripting.Fi
strSiteFolder = "d:\sites"
' For this version to work you need to give the relative path from the www root to the log files.
' The user running this script must have access rights to the logs or it won't work.
strLogPath = "\logs"
' e.g.
' strLogPath = "\logs"
' This will combine to create d:\sites\<site folder>\logs
'
' Functions
'
Function FileTotal(strLogName)
' A function that returns the number of bytes from a particular log file
intFileTotal = 0
intByteCurrent = 0
booFieldFound = "FALSE"
' Clear out any previous errors and initialize error handling
Set objFile = objFileSystem.GetFile(strL
Set objTextStream = objFile.OpenAsTextStream(1
Do
booIgnore = "FALSE"
strLine = objTextStream.ReadLine()
arrLine = split(strLine, " ")
' Get the field positions
If (arrLine(0) = "#Fields:") Then
intFieldPosition = 0
intFieldCount = 0
For Each strElement in arrLine
If (strElement = "sc-bytes") Then
intFieldPosition = intFieldCount - 1
booFieldFound = "TRUE"
End If
intFieldCount = intFieldCount + 1
Next
End If
' Ignore other lines starting with #
If (Left(arrLine(0), 1) = "#") Then
booIgnore = "TRUE"
End If
' Count up the total
If ((booFieldFound = "TRUE") and (booIgnore = "FALSE")) Then
If (Ubound(arrLine) => intFieldPosition) Then
intByteCurrent = arrLine(intFieldPosition)
intFileTotal = intFileTotal + intByteCurrent
End If
End If
Loop while not objTextStream.AtEndOfStrea
FileTotal = intFileTotal
End Function
Function FileName(strMonth, strYear)
' Creates the partial log filename from the Month and Year
If (strMonth < 10) Then
strMonth = "0" & strMonth
End If
strYear = Right(strYear, 2)
strPartialName = "ex" & strYear & strMonth
FileName = strPartialName
End Function
'
' Main Section
'
' Start out by running it for last month...
strMonth = DatePart("m",Date())
strYear = DatePart("yyyy",Date())
' Set it up to process logs from last month
If (strMonth = 1) Then
strYear = strYear - 1
strMonth = 12
Else
strMonth = strMonth - 1
End If
strPartialName = FileName(strMonth, strYear)
' Connect to the log folder to get the full path
Set objSiteFolder = objFileSystem.GetFolder(st
For Each objSite in objSiteFolder.SubFolders
' Make sure the logs folder exists first
strLogFolder = objSite.Path & strLogPath
If (objFileSystem.FolderExist
Set objFolder = objFileSystem.GetFolder(st
' Attempt to Connect to the W3SVC folder
For Each objSubFolder in objFolder.SubFolders
If ((InStr(objSubFolder.Name,
strLogFolder = objSubFolder.Path
booConnected = "TRUE"
End If
Next
Set objFolder = Nothing
Set objFolder = objFileSystem.GetFolder(st
intLogsTotal = 0
For Each objFile in objFolder.Files
If (InStr(objFile.Name, strPartialName) <> 0) Then
strLogFile = objFile.Path
intTotal = 0
intTotal = FileTotal(strLogFile)
intLogsTotal = intLogsTotal + intTotal
End If
Next
Response.Write("Total Bytes Used in Logs for " & objSite.Name & ": " & intLogsTotal & "<br />")
End If
Next
%>
</body>
</html>
ASKER
Total Bytes Used in Logs for acs: 0
Total Bytes Used in Logs for adr: 0
Total Bytes Used in Logs for AdvancedAudio: 0
Total Bytes Used in Logs for annabellegutman: 0
Total Bytes Used in Logs for atomiccomputerservices: 0
Total Bytes Used in Logs for Belayer: 0
etc.
I think I may have just realized what the problem is. AT the beginning of this months log files, we were not logging the bytes so the beginning of the log files doesn't have that field. Then we decided to start logging that info so we do have bytes later on. Could we try it for just the last day instead of the last month? That way the entire log, from beginning to end, will have bytes in it.
Total Bytes Used in Logs for adr: 0
Total Bytes Used in Logs for AdvancedAudio: 0
Total Bytes Used in Logs for annabellegutman: 0
Total Bytes Used in Logs for atomiccomputerservices: 0
Total Bytes Used in Logs for Belayer: 0
etc.
I think I may have just realized what the problem is. AT the beginning of this months log files, we were not logging the bytes so the beginning of the log files doesn't have that field. Then we decided to start logging that info so we do have bytes later on. Could we try it for just the last day instead of the last month? That way the entire log, from beginning to end, will have bytes in it.
If you want to make it process for this month instead of last comment out this section like below:
' Set it up to process logs from last month
' If (strMonth = 1) Then
' strYear = strYear - 1
' strMonth = 12
' Else
' strMonth = strMonth - 1
' End If
And it'll run for all the log files that are present for this month. Changing it to run for a single file is possible, but it would be quicker to check it works for this months logs.
ASKER
Still getting 0's across the board...
Okay, this is vbscript (rather than asp) that will process a single log file. Could you try it please? It won't produce much output, but it should say if it's finding the right things.
Set objFileSystem = CreateObject("Scripting.Fi
' Gets log file for 21st April
strLogName = "D:\sites\acs\logs\W3SVC66
intFileTotal = 0
intByteCurrent = 0
booFieldFound = "FALSE"
' Clear out any previous errors and initialize error handling
Set objFile = objFileSystem.GetFile(strL
Set objTextStream = objFile.OpenAsTextStream(1
Do
booIgnore = "FALSE"
strLine = objTextStream.ReadLine()
arrLine = split(strLine, " ")
' Get the field positions
If (arrLine(0) = "#Fields:") Then
wscript.echo "Found #Fields line"
intFieldPosition = 0
intFieldCount = 0
For Each strElement in arrLine
If (strElement = "sc-bytes") Then
intFieldPosition = intFieldCount - 1
booFieldFound = "TRUE"
wscript.echo "Located sc-bytes"
End If
intFieldCount = intFieldCount + 1
Next
End If
' Ignore other lines starting with #
If (Left(arrLine(0), 1) = "#") Then
booIgnore = "TRUE"
End If
' Count up the total
If ((booFieldFound = "TRUE") and (booIgnore = "FALSE")) Then
If (Ubound(arrLine) => intFieldPosition) Then
intByteCurrent = arrLine(intFieldPosition)
intFileTotal = intFileTotal + intByteCurrent
End If
End If
Loop while not objTextStream.AtEndOfStrea
wscript.echo intFileTotal
ASKER
Um, how do I go about running vbscript? Sorry, this isn't really my sorta thing...
Oops sorry...
Grab a copy of a log file (any of them).
Save the code above in a .vbs file, make sure it knows where the log file is with the line:
strLogName = "D:\sites\acs\logs\W3SVC66
Then run the script... it'll say if it found the field it needs, and the total for the file.
ASKER
I suppose I am opening this file in a web browser right? Is there something special I need to do in order to get the server to process it? When I open it now, it just comes up with the download file screen (open, save, etc...).
Ahh if it still needs running remotely use this one instead (as ASP):
<%
Set objFileSystem = CreateObject("Scripting.Fi
' Gets log file for 21st April
strLogName = "D:\sites\acs\logs\W3SVC66
intFileTotal = 0
intByteCurrent = 0
booFieldFound = "FALSE"
' Clear out any previous errors and initialize error handling
Set objFile = objFileSystem.GetFile(strL
Set objTextStream = objFile.OpenAsTextStream(1
Do
booIgnore = "FALSE"
strLine = objTextStream.ReadLine()
arrLine = split(strLine, " ")
' Get the field positions
If (arrLine(0) = "#Fields:") Then
Response.Write "Found #Fields line"
intFieldPosition = 0
intFieldCount = 0
For Each strElement in arrLine
If (strElement = "sc-bytes") Then
intFieldPosition = intFieldCount - 1
booFieldFound = "TRUE"
Response.Write "Located sc-bytes"
End If
intFieldCount = intFieldCount + 1
Next
End If
' Ignore other lines starting with #
If (Left(arrLine(0), 1) = "#") Then
booIgnore = "TRUE"
End If
' Count up the total
If ((booFieldFound = "TRUE") and (booIgnore = "FALSE")) Then
If (Ubound(arrLine) => intFieldPosition) Then
intByteCurrent = arrLine(intFieldPosition)
intFileTotal = intFileTotal + intByteCurrent
End If
End If
Loop while not objTextStream.AtEndOfStrea
Response.Write intFileTotal
%>
ASKER
Found #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytesFound #Fields lineLocated sc-bytes126363
hmm see that's odd.. none of the code changed except for a few additional response.writes but it worked... how frustrating..
ASKER
so this aint gonna happen?
No reason why it shouldn't.... it's probably something silly like a typo creeping in when it's being copied. I'll setup a downloadable version on my website tomorrow and post that one in.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
still all 0's
Hmm okay I'm stuck - short of it being something simple like permissions I can find no reason that it wouldn't work.
After all, running it on an individual file above did work... There's been no difference in the user you run it as, or anything else?
ASKER
nope, same user for both files. it's all the default windows 2003 setup for users.
One last try perhaps, although I doubt it will make any difference?
Made sure it closed off the File Object before using it again.
Here again...
http://www.highorbit.co.uk/Bandwidth.asp
ASKER
nope no difference
Hmm... sorry that isn't working, not too helpful after all that...
ASKER
Yeah, could you please?
Any chance you'd like to give Chris-Dent a few points for his efforts?
(this is not an unofficial request, no pressure)
(this is not an unofficial request, no pressure)
If so, tell me how many you'd like to give. If not, ie. if you need them for the new question, that's fine, too.
ASKER
how bout 100 of the original 500
Sounds great. Would you like me to make the change?
A cheaper and simpler solution would be a log file analysis tool that can break down bandwidth use by website. A good example of that is LogFileManager 3 - www.logfilemanager.com.