Never been to TextSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

About this user

AJ http://ajz.textdriven.com

« Newer Snippets
Older Snippets »
4 total  XML / RSS feed 

rsrcmeter v2

TextDrive: Simple disk usage and HTTP bandwidth counts
Updated version from http://textsnippets.com/posts/show/632
This script will allow a TextDrive account holder to easily see their disk usage and monthly HTTP bandwidth consumption, until TextPanel provides the information.
The first time you use rsrcmeter, it may take additional time, as it will be scanning every Apache/HTTP log file for usage information and caching it by month.

--> Get Easy Install Instructions, Etc. at http://rsrcmeter.textjoy.com/.

Sample output:
Disk usage: 23.7227 MiB (Quota: 10.0000 GiB | 0.2% used)
Bandwidth:
Nov 2006: 0.5494 MiB (Month to Date)
Oct 2006: 0.5087 MiB
Sep 2006: 0.5523 MiB
Aug 2006: 1.1567 MiB


#!/usr/local/bin/ruby
# Unofficial TxD Disk & HTTP Bandwidth Usage Meter (rsrcmeter)
# Version 2.0.2
# Written by AJ Zmudosky
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND WITHOUT WARRANTY OF
# ANY KIND. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
# DAMAGES HOWEVER CAUSED, AND ON ANY THEORY OF LIABILITY, ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.

require 'date'
require 'optparse'

# E-mail regexp
module RFC2822
  EmailAddress = begin
    alpha = "a-zA-Z"
    digit = "0-9"
    atext = "[#{alpha}#{digit}\!\#\$\%\&\'\*+\/\=\?\^\_\`\{\|\}\~\-]"
    dot_atom_text = "#{atext}+([.]#{atext}*)*"
    dot_atom = "#{dot_atom_text}"
    qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
    text = "[\\x01-\\x09\\x11\\x12\\x14-\\x7f]"
    quoted_pair = "(\\x5c#{text})"
    qcontent = "(?:#{qtext}|#{quoted_pair})"
    quoted_string = "[\"]#{qcontent}+[\"]"
    atom = "#{atext}+"
    word = "(?:#{atom}|#{quoted_string})"
    obs_local_part = "#{word}([.]#{word})*"
    local_part = "(?:#{dot_atom}|#{quoted_string}|#{obs_local_part})"
    no_ws_ctl = "\\x01-\\x08\\x11\\x12\\x14-\\x1f\\x7f"   
    dtext = "[#{no_ws_ctl}\\x21-\\x5a\\x5e-\\x7e]"
    dcontent = "(?:#{dtext}|#{quoted_pair})"
    domain_literal = "\\[#{dcontent}+\\]"
    obs_domain = "#{atom}([.]#{atom})*"
    domain = "(?:#{dot_atom}|#{domain_literal}|#{obs_domain})"
    addr_spec = "#{local_part}\@#{domain}"
    pattern = /^#{addr_spec}$/
  end
end

# Default options
opt = {
  :base_dir => ENV['HOME'],
  :stat_file => 'histstat',
  :temp_file => 'temp-rsrcmeter-bwcalc',
  :bw_months => 5
}

# Our option flag parsing
OptionParser.new do |opts|
  opts.banner = "Unofficial TxD Disk & HTTP Bandwidth Usage Meter\nUsage: rsrcmeter [options]"
  
  opts.on("-b", "--base BASE", "Change the base directory, defaults to user's $HOME", String) {|base|
    if File.exists?(base)
      opt[:base_dir] = base
    else
      raise(ArgumentError, "Directory (#{base}) specified with -b does not exist")
    end
  }
  
  opts.on("--stat-file FILE", "Change default historical data file from '#{opt[:stat_file]}'", String) {|file|
    opt[:stat_file] = file
  }
  
  opts.on("--temp-file FILE", "Change default temporary file from '#{opt[:temp_file]}'", String) {|file|
    opt[:temp_file] = file
  }
  
  opts.on("-m NUM", "Number of months' bandwidth to show prior to current month (default: #{opt[:bw_months]})", Integer) {|mons|
    opt[:bw_months] = mons if mons > 0
  }
  
  opts.on("-e", "--email ADDRESS", "E-mail results to ADDRESS *instead* of outputting to the screen", String) {|addr|
    if RFC2822::EmailAddress =~ addr
      opt[:email_to] = addr
    else
      raise(ArgumentError, "Invalid e-mail address provided to -e")
    end
  }
  
  opts.on_tail("-h", "--help", "Show this message") do
    puts opts
    exit
  end
end.parse!

Dir.chdir(opt[:base_dir])
File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])

# Look for existing monthly statistics file
if File.exists?(opt[:stat_file])
  # Load and process existing stats
  @stats = Array.new
  lines = File.readlines(opt[:stat_file])
  lines.each {|l| (@stats << [l.chomp.split(',')[0], l.chomp.split(',')[1].to_f]) unless (l.strip)[0,1] == '#'}
  @stats.sort!
  # Determine if any months need to be added
  if Date.today.month == 1
    pm_year = Date.today.year - 1
    pm_month = 12
  else
    pm_year = Date.today.year
    pm_month = Date.today.month - 1
  end
  stop_month = pm_year.to_s + (pm_month < 10 ? '0' : '') + pm_month.to_s
  proc_year = @stats.last[0][0,4].to_i
  proc_month = @stats.last[0][4,2].to_i
  proc_year += 1 if proc_month == 12
  proc_month = (proc_month == 12) ? 1 : proc_month + 1
  proc_str = proc_year.to_s + (proc_month < 10 ? '0' : '') + proc_month.to_s
  # Add any months not already calculated
  while proc_str <= stop_month
    datestr = proc_str + "??"
    File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])
    `cat logs/access_log.#{datestr} 2>/dev/null > #{opt[:temp_file]}`
    `cat domains/*/logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
    `zcat logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
    `zcat domains/*/logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
    month_usage = `cat #{opt[:temp_file]} | awk '{sum += $10} END {print sum}'`.chomp.to_i
    @stats << [proc_str, month_usage]
    # advance counting
    proc_year += 1 if proc_month == 12
    proc_month = (proc_month == 12) ? 1 : proc_month + 1
    proc_str = proc_year.to_s + (proc_month < 10 ? '0' : '') + proc_month.to_s
  end
# Statistics files doesn't exist
else
  # Look for earliest log file
  file_list = Array.new
  Dir.foreach(opt[:base_dir] + "/logs") {|i| file_list << i if /^access_log.\d{8}/ =~ i}
  if File.exists?(opt[:base_dir] + "/domains")
    domains = Array.new
    Dir.foreach(opt[:base_dir] + "/domains") {|dom| domains << dom if /^\w+\.\w+/ =~ dom}
    domains.each {|dom| Dir.foreach(opt[:base_dir] + "/domains/" + dom + "/logs") {|i| file_list << i if /^access_log.\d{8}/  =~ i}}
  end
  file_list.sort!
  unless Date.today.year.to_s + Date.today.month.to_s == file_list.first[11,6]
    # Process from earliest_log year/month forward
    earliest_log_year = file_list.first[11,4]
    earliest_log_month = file_list.first[15,2]
    @stats = Array.new
    earliest_log_year.to_i.upto(Date.today.year) do |year|
      start_month = (earliest_log_year.to_i == year) ? earliest_log_month.to_i : 1;
      start_month.upto(12) do |month|
        unless (year == Date.today.year and month >= Date.today.month)
          month = "0" + month.to_s if month < 10
          datestr = year.to_s + month.to_s + '??'
          File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])
          `cat logs/access_log.#{datestr} 2>/dev/null > #{opt[:temp_file]}`
          `cat domains/*/logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
          `zcat logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
          `zcat domains/*/logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
          month_usage = `cat #{opt[:temp_file]} | awk '{sum += $10} END {print sum}'`.chomp.to_i
          @stats << [year.to_s + month.to_s, month_usage]
        end
      end
    end
  end
end

# Write @stats back to opt[:stat_file] to record any changes
File.open(opt[:stat_file], 'w') {|f|
  f.puts "# rsrcmeter historical statistics file"
  f.puts "# Contains only completed months"
  @stats.each {|i| f.puts i[0] + ',' + i[1].to_s}
}

# Calculate bandwidth consumption for current month
datestr = Date.today.year.to_s + Date.today.month.to_s + "??"
`cat logs/access_log 2>/dev/null > #{opt[:temp_file]}`
`cat domains/*/logs/access_log 2>/dev/null >> #{opt[:temp_file]}`
`cat logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
`cat domains/*/logs/access_log.#{datestr} 2>/dev/null >> #{opt[:temp_file]}`
`zcat logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
`zcat domains/*/logs/access_log.#{datestr}.gz 2>/dev/null >> #{opt[:temp_file]}`
usage = `cat #{opt[:temp_file]} | awk '{sum += $10} END {print sum}'`.chomp.to_f / 1024 / 1024
File.delete(opt[:temp_file]) if File.exists?(opt[:temp_file])
# Determine disk usage
quotaline = `quota -g | tail -n 1`
disk_usage = `echo -n "#{quotaline}" | awk '{print $2}'`.to_f
disk_quota = `echo -n "#{quotaline}" | awk '{print $3}'`.to_f
disk_percent_used = (disk_usage / disk_quota) * 100

# Output results
results = ""
results << "Disk usage: " + sprintf("%.4f", disk_usage / 1024) + " MiB (Quota: " + sprintf("%.4f", disk_quota / 1024 / 1024) +" GiB | " + sprintf("%.1f", disk_percent_used) + "% used)\n"
results << "Bandwidth:\n" + Date::ABBR_MONTHNAMES[Date.today.month] + " " + Date.today.year.to_s + ": " + sprintf("%.4f", usage) + " MiB (Month to Date)\n"
hist_usage = @stats.last(opt[:bw_months]).reverse
hist_usage.each {|h| results << Date::ABBR_MONTHNAMES[Date.parse(h[0] + "01").month] + ' ' + h[0][0,4] + ": " + sprintf("%.4f", (h[1].to_f / 1024 / 1024)) + " MiB\n"}

# We're either e-mailing or outputting
if opt[:email_to]
  t = Time.now.strftime("%a %d %B %Y %H:%M:%S %Z")
  message = <<EOM
From: TxD Resource Meter <#{ENV['USER']}-noreply@#{`/bin/hostname`.chomp}>
To: #{opt[:email_to]}
Subject: [TxD Resource Meter] #{t} report for #{ENV['USER']}
X-Mailer: rsrcmeter | http://textsnippets.com/posts/show/842

Resource Report - #{t}
#{results}
---------------
Generated by rsrcmeter
EOM
  File.open("temp-emailresult", "w") { |file| file.print message }
  `cat temp-emailresult | /usr/sbin/sendmail -t`
  File.delete("temp-emailresult")
else
  puts results
end

File buffer chunked processing

For future reference from: http://forum.textdrive.com/viewtopic.php?pid=105585#p105585
(Johan via Bernard)

Reading file buffer in chunks to prevent reaching process memory limits.

File.open("", "wb") do |f|
  while buff = file_field.read(4096)
    f.write(buff)
  end
end

rsrcmeter for TxD

Newer version at http://textsnippets.com/posts/show/842

TextDrive: Simple disk usage and HTTP bandwidth counts
This is an updated version of http://textsnippets.com/posts/show/621

#!/usr/local/bin/ruby
Dir.chdir(ENV['HOME'])
# Disk usage
quotaline = `quota -g | tail -n 1`
usage = `echo -n "#{quotaline}" | awk '{print $2}'`.to_f
quota = `echo -n "#{quotaline}" | awk '{print $3}'`.to_f
percent_used = (usage / quota) * 100
puts "Disk usage: " + sprintf("%.4f", usage/1024) + " MiB (Quota: " + sprintf("%.4f", quota/1024/1024) +" GiB; " + sprintf("%.1f", percent_used) + "% used)"

# HTTP Bandwidth
print "Calculating Bandwidth Usage..."
month = `date +"%B %Y"`.chomp
access_logs="access_log." + `date +%Y%m`.chomp + "??"
system("cat logs/access_log 2>/dev/null > temp-bandwidthcount") # Today's log
system("cat domains/*/logs/access_log 2>/dev/null >> temp-bandwidthcount")
system("cat logs/#{access_logs} 2>/dev/null >> temp-bandwidthcount") # Any logs not (yet) gzipped
system("cat domains/*/logs/#{access_logs} 2>/dev/null >> temp-bandwidthcount")
system("zcat logs/#{access_logs}.gz 2>/dev/null >> temp-bandwidthcount") # Gzipped logs from previous days
system("zcat domains/*/logs/#{access_logs}.gz 2>/dev/null >> temp-bandwidthcount")

usage = `cat temp-bandwidthcount | awk '{sum += $10} END {print sum}'`.chomp.to_f / 1024 / 1024
File.delete("temp-bandwidthcount")

30.times {print "\b"}
puts "Bandwidth used for #{month}: " + sprintf("%.4f", usage) + " MiB"


Installing:
Easy as 1..2..3:
curl -o rsrcmeter http://ajz.textdriven.com/rsrcmeter.txt
chmod u+x rsrcmeter
./rsrcmeter

Using in Webmin (Under Run Processes, Command to run):
export HOME="/users/home/YOURUSERNAME"; $HOME/rsrcmeter


MD5 hash: 0364b47675fee1902db1a32703cecf3f

Sample output:
Disk usage: 2.2910 MiB (Quota: 1.9073 GiB; 0.1% used)
Bandwidth used for August 2006: 0.5773 MiB


Confirmed to work on:
- Cardero,
- Davie (by rsimplicio),
- Pendrell (by iolaire),
- Thurlow (by janovetz),
- Bidwell & Jervis (by springworks),
- Chilco (by atl),
- Burnaby (by igner),
- Broughton (Biz Server, by Rich),
- Howe (scoobyfoo),
- Nicola (lderezinski),
- Jervis (mjboyle), and
- One (robertb)
*Should work on any TxD shared/business server.*

showbandwidth (for TxD)

This has been superseded by http://textsnippets.com/posts/show/632 (includes account disk usage)!

#!/usr/local/bin/bash
cd ~
export ACCESS_LOGS=access_log.`date +%Y%m`??
cat logs/access_log 2>/dev/null > temp-bandwidthcount
cat domains/*/logs/access_log 2>/dev/null >> temp-bandwidthcount
cat logs/$ACCESS_LOGS 2>/dev/null >> temp-bandwidthcount
cat domains/*/logs/$ACCESS_LOGS 2>/dev/null >> temp-bandwidthcount
zcat logs/$ACCESS_LOGS.gz 2>/dev/null >> temp-bandwidthcount
zcat domains/*/logs/$ACCESS_LOGS.gz 2>/dev/null >> temp-bandwidthcount
echo -n "Bandwidth used for `date +"%B %Y"`: "
cat temp-bandwidthcount | awk '{sum += $10} END {print sum/1024/1024,"MiB"}'
rm temp-bandwidthcount


1. Upload as showbandwidth
2. chmod u+x it
3. run it (~# ./showbandwidth) to get your current month's (HTTP) bandwidth usage.
Output Sample: Bandwidth used for August 2006: 0.46237 MB

Original credit to Filip: http://textsnippets.com/posts/show/346.

Old version (only use if you have changed where Apache saves its log files):
#!/usr/local/bin/bash
cd ~
export ACCESS_LOGS=access_log.`date +%Y%m`??
cat `find . -name 'access_log' 2>/dev/null` 2>/dev/null > temp-bandwidthcount # Today's log
cat `find . -name "$ACCESS_LOGS" 2>/dev/null` 2>/dev/null >> temp-bandwidthcount # For any not gzipped
zcat `find . -name "$ACCESS_LOGS.gz" 2>/dev/null` 2>/dev/null >> temp-bandwidthcount
echo -n "Bandwidth used for `date +"%B %Y"`: "
cat temp-bandwidthcount | awk '{sum += $10} END {print sum/1024/1024,"MB"}'
rm temp-bandwidthcount
« Newer Snippets
Older Snippets »
4 total  XML / RSS feed