symbiosis-generate-stats 5.01 KB
Newer Older
1
2
3
#!/usr/bin/ruby1.8
#
# NAME
4
#   symbiosis-generate-stats - Generate statistics for domains.
5
6
7
#
#
# SYNOPSIS
8
#  symbiosis-generate-stats [ --template | -t <filename> ] [ --force | -f ]
9
#       [ -h | --help ] [-m | --manual] [ -v | --verbose ]
10
11
12
#
#
# OPTIONS
13
#  -t, --template <file>   Set the webalizer config template file. Defaults to
14
15
#                          /etc/symbiosis/apache.d/webalizer.conf.erb.
#
16
17
18
#  -f, --force             Force regeneration of the webalizer configuration
#                          snippet for all domains.
#
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#  -h, --help              Show a help message, and exit.
#
#  -m, --manual            Show this manual, and exit.
#
#  -v, --verbose           Show verbose errors
#
#
# USAGE
#
# This script is designed to be invoked once per day and update the
# web-visible access statistics for each hosted Symbiosis domain.
#
# The script is assumed to be invoked once per day, via /etc/cron.daily/.
#
# AUTHOR
#
#   Steve Kemp <steve@bytemark.co.uk>
#


39
40
41
#
# Standard ruby
#
42
require 'getoptlong'
43

44

Steve Kemp's avatar
Steve Kemp committed
45

46
47
48
#
#  The options set by the command line.
#
49
template     = '/etc/symbiosis/apache.d/webalizer.conf.erb'
50
51
52
help         = false
manual       = false
$VERBOSE     = false
53
$FORCE       = false
54
55
56
57
58


opts = GetoptLong.new(
                      [ '--help',       '-h', GetoptLong::NO_ARGUMENT ],
                      [ '--manual',     '-m', GetoptLong::NO_ARGUMENT ],
59
                      [ '--verbose',    '-v', GetoptLong::NO_ARGUMENT ],
60
                      [ '--force',      '-f', GetoptLong::NO_ARGUMENT ],
61
                      [ '--template',   '-t', GetoptLong::REQUIRED_ARGUMENT ]
62
63
64
65
66
67
68
69
70
71
72
73
                      )


begin
  opts.each do |opt,arg|
    case opt
    when '--help'
      help = true
    when '--manual'
      manual = true
    when '--verbose'
      $VERBOSE = true
74
    when '--force'
75
      $FORCE = true
76
77
    when '--template'
      template = arg
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    end
  end
rescue
  # any errors, show the help
  help = true
end


#
# CAUTION! Here be quality kode.
#
if manual or help

  # Open the file, stripping the shebang line
  lines = File.open(__FILE__){|fh| fh.readlines}[1..-1]

  found_synopsis = false

  lines.each do |line|

    line.chomp!
    break if line.empty?

    if help and !found_synopsis
      found_synopsis = (line =~ /^#\s+SYNOPSIS\s*$/)
      next
    end

    puts line[2..-1].to_s

    break if help and found_synopsis and line =~ /^#\s*$/

  end

  exit 0
end

115
116
117
118
119
120
#
# Symbiosis libraries -- required here so they're not needed during the build
# process for manpage generation.
#
require 'symbiosis/domains'
require 'symbiosis/domain/http'
121
122
123
require 'symbiosis/config_files/webalizer'

def verbose(s) ; puts s if $VERBOSE ; end
124
125

#
126
#  Potentially we process each domain.
127
#
128
Symbiosis::Domains.each do |domain|
129
  verbose "Considering domain: #{domain}"
130

131
132
133
  #
  # Are statistics disabled for this domain?
  #
134
  unless ( domain.should_have_stats? )
135
    verbose "\tSkipping as stats have been disabled."
136
137
138
139
140
141
    next
  end

  #
  # Skip symlinks
  #
142
143
  if ( domain.is_alias? )
    verbose "\tSkipping as it is an symlink to #{domain.directory}."
144
145
146
147
148
149
150
    next
  end

  #
  # OK now we need to look for a logfile, or two.
  #
  #  access.log     for HTTP accesses.
151
  #  ssl_access.log for HTTPS accesses.
152
153
154
  #
  process = Array.new()

155
156
157
  %w( access.log.1 ssl_access.log.1 ).each do |name|
    log = File.join( domain.log_dir, name ) 
    process.push(log) if File.exists?(log) 
Steve Kemp's avatar
Steve Kemp committed
158
159
  end

160
  #
Steve Kemp's avatar
Steve Kemp committed
161
  # If we didn't find a logfile we're done.
162
  #
Steve Kemp's avatar
Steve Kemp committed
163
  if ( process.empty? )
164
    verbose "\tSkipping this domain, no suitable logfiles found"
165
166
167
168
    next
  end

  #
Steve Kemp's avatar
Steve Kemp committed
169
  #  Create a configuration file, if one wasn't found.
170
  #
171
  webalizer_conf = File.join( domain.config_dir, "webalizer.conf" )
172

173
  config          = Symbiosis::ConfigFiles::Webalizer.new(webalizer_conf, "#")
174
175
  config.template = template 
  config.domain   = domain
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

  write_config = false

  #
  # This is taken from symbiosis-create-stes
  #
  if ( $FORCE )
    verbose "\tForcing re-creation of configuration due to --force."
    write_config = true

  elsif config.exists?

    if config.changed?
      verbose "\tNot updating configuration, as it has been edited by hand."
      write_config = false

    elsif config.outdated?
      verbose "\tRe-creating configuration as it is out of date."
      write_config = true

    else
      verbose "\tConfiguring already present and up-to date."
      write_config = false

Steve Kemp's avatar
Steve Kemp committed
200
    end
201
202
203
204
205

  else
    verbose "\tConfiguring site for the first time"
    write_config = true

Steve Kemp's avatar
Steve Kemp committed
206
  end
207

208
209
210
211
  #
  # Write the config if we need to.
  #
  config.write if write_config
212

Steve Kemp's avatar
Steve Kemp committed
213
214
215

  #
  #  If we don't have a statistics directory then we need to create it,
216
217
  # and we need to create it with the domains' UID/GID.  This method will not
  # error if the directory already exists.
218
  #
219
  domain.create_dir( domain.stats_dir )
Steve Kemp's avatar
Steve Kemp committed
220
221
222

  #
  #  Now process each logfile.
223
  #
224
  puts "\tRunning webalizer against #{process.join(" ")}" if $VERBOSE
225

226
227
228
229
  #
  #  Now run it under sudo, as the user ID of the domain.
  #
  system( "cd #{domain.config_dir} && sudo -u '\##{domain.uid}' -- webalizer -q #{process.join(" ")} >/dev/null 2>/dev/null" )
230

231
232
233
234
end