From cee939b527e82237f89eb8eece62610854ac888a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 7 Sep 2009 15:49:55 -0700 Subject: Switch to hand-rolled packaging/distro scripts Several bikeshed reasons brought me to this point: * I like the README.html layout more than any default index.html even if it's using README content. Having links on the side helps navigation IMHO. * publish_docs preserves timestamps to improve cache hit rate * git is used to maintain the manifest at packaging/release-time so my changesets have less noise in them * git is used to generate history files (from tag messages), this is a more DRY approach to me. * I don't like the ".txt" suffix being translated to "_txt.html" in URLs. I don't like the ".txt" suffix in general. * I don't like Manifest.txt showing up in my RDoc --- .document | 4 ++ .gitignore | 2 + GNUmakefile | 58 +++++++++++++++++------- History.txt | 45 ------------------- Manifest.txt | 15 ------- README | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.txt | 137 -------------------------------------------------------- Rakefile | 48 +++++++++++--------- clogger.gemspec | 30 +++++++++++++ 9 files changed, 242 insertions(+), 234 deletions(-) create mode 100644 .document delete mode 100644 History.txt delete mode 100644 Manifest.txt create mode 100644 README delete mode 100644 README.txt create mode 100644 clogger.gemspec diff --git a/.document b/.document new file mode 100644 index 0000000..b9cb90b --- /dev/null +++ b/.document @@ -0,0 +1,4 @@ +README +History +lib +ext/clogger_ext/clogger.c diff --git a/.gitignore b/.gitignore index 6d1222b..31a1a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ Makefile /doc /local.mk /pkg +/.manifest +/History diff --git a/GNUmakefile b/GNUmakefile index b57c947..b690ca9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,5 +1,6 @@ all:: test ruby = ruby +rake = rake -include local.mk @@ -7,10 +8,6 @@ ifeq ($(DLEXT),) # "so" for Linux DLEXT := $(shell $(ruby) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]') endif -ifeq ($(RUBY_VERSION),) - RUBY_VERSION := $(shell $(ruby) -e 'puts RUBY_VERSION') -endif - ext/clogger_ext/Makefile: ext/clogger_ext/clogger.c ext/clogger_ext/extconf.rb cd ext/clogger_ext && $(ruby) extconf.rb @@ -29,10 +26,13 @@ test-pure: test: test-ext test-pure -Manifest.txt: - git ls-files > $@+ - cmp $@+ $@ || mv $@+ $@ - $(RM) $@+ +History: + $(rake) -s history > $@+ + mv $@+ $@ + +.manifest: History + (git ls-files; for i in $^ $@; do echo $$i; done) | LC_ALL=C sort > $@+ + mv $@+ $@ VERSION := $(shell git describe 2>/dev/null | sed 's/^v//') @@ -41,6 +41,8 @@ v := /^v$(VERSION)$$/ vPREV := $(shell git tag -l 2>/dev/null | sed -n -e '$(v)!h' -e '$(v){x;p;q}') release_notes := release_notes-$(VERSION).txt release_changes := release_changes-$(VERSION).txt +release-notes: $(release_notes) +release-changes: $(release_changes) $(release_changes): verify git diff --stat $(vPREV) v$(VERSION) > $@+ echo >> $@+ @@ -55,24 +57,48 @@ verify: @test -n "$(VERSION)" || { echo >&2 VERSION= not defined; exit 1; } git rev-parse --verify refs/tags/v$(VERSION)^{} @test -n "$(VISUAL)" || { echo >&2 VISUAL= not defined; exit 1; } - -package: verify git diff-index --quiet HEAD^0 test `git rev-parse --verify HEAD^0` = \ `git rev-parse --verify refs/tags/v$(VERSION)^{}` - $(RM) -r pkg - unset CLOGGER_EXT; rake package VERSION=$(VERSION) - CLOGGER_EXT=1 rake package VERSION=$(VERSION) + +pkg/clogger-$(VERSION).gem: .manifest History clogger.gemspec + gem build clogger.gemspec + mkdir -p pkg + mv $(@F) $@ + +pkg/clogger-$(VERSION).tgz: HEAD = v$(VERSION) +pkg/clogger-$(VERSION).tgz: .manifest History + $(RM) -r $(basename $@) + git archive --format=tar --prefix=$(basename $@)/ $(HEAD) | tar xv + install -m644 $^ $(basename $@) + cd pkg && tar cv $(basename $(@F)) | gzip -9 > $(@F)+ + mv $@+ $@ + +package: pkg/clogger-$(VERSION).gem pkg/clogger-$(VERSION).tgz # not using Hoe's release system since we release 2 gems but only one tgz -release: package Manifest.txt $(release_notes) $(release_changes) +release: package $(release_notes) $(release_changes) rubyforge add_release -f -n $(release_notes) -a $(release_changes) \ clogger clogger $(VERSION) pkg/clogger-$(VERSION).gem rubyforge add_file \ clogger clogger $(VERSION) pkg/clogger-$(VERSION).tgz rubyforge add_release -f -n $(release_notes) -a $(release_changes) \ clogger clogger_ext $(VERSION) pkg/clogger_ext-$(VERSION).gem - rake post_news endif -.PHONY: test doc Manifest.txt release +doc: .document History + rdoc -Na -t "$(shell sed -ne '1s/^= //p' README)" + install -m644 COPYING doc/COPYING + cd doc && ln README.html tmp.html && mv tmp.html index.html + +# publishes docs to http://clogger.rubyforge.org/ +# this preserves timestamps as best as possible to help HTTP caches out +# git set-file-times can is here: http://git-scm.org/gitwiki/ExampleScripts +publish_doc: + git set-file-times + $(RM) -r doc + $(MAKE) doc + rsync -av --delete doc/ rubyforge.org:/var/www/gforge-projects/clogger/ + git ls-files | xargs touch + +.PHONY: test doc .manifest release History diff --git a/History.txt b/History.txt deleted file mode 100644 index a989a0a..0000000 --- a/History.txt +++ /dev/null @@ -1,45 +0,0 @@ -=== 0.0.5 / 2009-09-02 - - The following variables are now exposed: $request_method, - $content_length and $content_type. Additionally, attempts - to use $http_content_length or $http_content_type will be - remapped to use the non-"$http_"-prefixed variable instead - since the "$http_"-variants of those variables is not allowed - by Rack. - -=== 0.0.4 / 2009-09-02 - - The pure Ruby version now escapes with uppercase A-F - characters to match nginx log output. There are now extra - checks against badly behaving Rack applications and 500 - errors will be logged before TypeError is raised if the - application response does not conform (minimally) to Rack - expectations. Finally, handling of $request (requests - without "HTTP_VERSION" set in the Rack env) should now be - logged correctly without unnecessary trailing characters. - - Hackers: the primary git repository has been moved to - git://git.bogomips.org/clogger.git for now since I'm having - issues with pushing to Rubyforge (seems related to Support - Requests item #26185). - -=== 0.0.3 / 2009-08-29 - - The MRI extension clogger_ext gets GC bug fix and - cleanups/robustness improvements. It should now be more - tolerant of misbehaving applications in that it'll be less - likely to segfault. No changes to the (recommended) pure - implementation. - -=== 0.0.2 / 2009-08-29 - -* 2 bug fixes - - * support "$request_uri" as a log variable - * Log bad/invalid app responses as 500 errors - -=== 0.0.1 / 2009-08-28 - -* 1 major enhancement - - * initial release diff --git a/Manifest.txt b/Manifest.txt deleted file mode 100644 index c627799..0000000 --- a/Manifest.txt +++ /dev/null @@ -1,15 +0,0 @@ -.gitignore -COPYING -GNUmakefile -History.txt -Manifest.txt -README.txt -Rakefile -ext/clogger_ext/clogger.c -ext/clogger_ext/extconf.rb -ext/clogger_ext/ruby_1_9_compat.h -lib/clogger.rb -lib/clogger/format.rb -lib/clogger/pure.rb -setup.rb -test/test_clogger.rb diff --git a/README b/README new file mode 100644 index 0000000..707b851 --- /dev/null +++ b/README @@ -0,0 +1,137 @@ += Clogger - configurable request logging for Rack + +* http://clogger.rubyforge.org/ +* mailto:clogger@librelist.com + +== DESCRIPTION + +Clogger is Rack middleware for logging HTTP requests. The log format +is customizable so you can specify exactly which fields to log. + +== FEATURES + +* highly customizable with easy-to-read nginx-like log format variables. + +* pre-defines Apache Common Log Format, Apache Combined Log Format and + Rack::CommonLogger (as distributed by Rack 1.0) formats. + See Clogger::Format for the predefined formats. + +* Untrusted values are escaped (all HTTP headers, request URI components) + to make life easier for HTTP log parsers. The following bytes are escaped: + + ' (single quote) + " (double quote) + all bytes in the range of \x00-\x1F + +== SYNOPSIS + +Clogger may be loaded as Rack middleware in your config.ru: + + require "clogger" + use Clogger, + :format => Clogger::Format::Combined, + :logger => File.open("/path/to/log", "ab") + run YourApplication.new + +If you're using Rails 2.3.x or later, in your config/environment.rb +somewhere inside the "Rails::Initializer.run do |config|" block: + + config.middleware.use 'Clogger', + :format => Clogger::Format::Combined, + :logger => File.open("/path/to/log", "ab") + +== VARIABLES + +* $http_* - HTTP request headers (e.g. $http_user_agent) +* $sent_http_* - HTTP response headers (e.g. $sent_http_content_length) +* $content_length - HTTP request body size + ($http_content_length is not allowed by Rack) +* $content_type - HTTP request content type + ($http_content_type is not allowed by Rack) +* $cookie_* - HTTP request cookie (e.g. $cookie_session_id) + Rack::Request#cookies must have been used by the underlying application + to parse the cookies into a hash. +* $request_method - the HTTP request method (e.g. GET, POST, HEAD, ...) +* $path_info - path component requested (e.g. /index.html) +* $query_string - request query string (not including leading "?") +* $request_uri - the URI requested ($path_info?$query_string) +* $request - the first line of the HTTP request + ($request_method $request_uri $http_version) +* $request_time, $request_time{PRECISION} - time taken for request + (including response body iteration). PRECISION defaults to 3 + (milliseconds) if not specified but may be specified anywhere from + 0(seconds) to 6(microseconds). +* $time_local, $time_local{FORMAT} - current local time, FORMAT defaults to + "%d/%b/%Y:%H:%M:%S %z" but accepts any strftime(3)-compatible format +* $time_utc, $time_utc{FORMAT} - like $time_local, except with UTC +* $usec - current time in seconds.microseconds since the Epoch +* $msec - current time in seconds.milliseconds since the Epoch +* $body_bytes_sent - bytes in the response body (Apache: %B) +* $response_length - body_bytes_sent, except "-" instead of "0" (Apache: %b) +* $remote_user - HTTP-authenticated user +* $remote_addr - IP of the requesting client socket +* $ip - X-Forwarded-For request header if available, $remote_addr if not +* $pid - process ID of the current process +* $e{Thread.current} - Thread processing the request +* $e{Actor.current} - Actor processing the request (Revactor or Rubinius) + +== REQUIREMENTS + +* Ruby, Rack + +== DEVELOPMENT + +The latest development happens in git and is published to the following: + + git://git.bogomips.org/clogger.git + git://repo.or.cz/clogger.git + +You may also browse and download snapshot tarballs: + +* http://git.bogomips.org/cgit/clogger.git (cgit) +* http://repo.or.cz/w/clogger.git (gitweb) + +The mailing list (see below) is central for coordination and +development. Patches should always be sent inline +(git format-patch -M + git send-email) so we can reply to them inline. + +== CONTACT + +All feedback (bug reports, user/development dicussion, patches, pull +requests) go to the mailing list. + +* mailto:clogger@librelist.com + +Do not send HTML mail or attachments. Do not top post. + +== INSTALL + +For all Rubygems users: + + gem install clogger + +If you're using MRI 1.8/1.9 and have a build environment, you can also try: + + gem install clogger_ext + +If you do not use Rubygems, you may also use setup.rb from tarballs from +the Rubyforge project page: + +* http://rubyforge.org/frs/?group_id=8896 + +== LICENSE + +Copyright (C) 2009 Eric Wong and contributors. + +Clogger is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation, version 3.0. + +Clogger is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with Clogger; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 diff --git a/README.txt b/README.txt deleted file mode 100644 index 707b851..0000000 --- a/README.txt +++ /dev/null @@ -1,137 +0,0 @@ -= Clogger - configurable request logging for Rack - -* http://clogger.rubyforge.org/ -* mailto:clogger@librelist.com - -== DESCRIPTION - -Clogger is Rack middleware for logging HTTP requests. The log format -is customizable so you can specify exactly which fields to log. - -== FEATURES - -* highly customizable with easy-to-read nginx-like log format variables. - -* pre-defines Apache Common Log Format, Apache Combined Log Format and - Rack::CommonLogger (as distributed by Rack 1.0) formats. - See Clogger::Format for the predefined formats. - -* Untrusted values are escaped (all HTTP headers, request URI components) - to make life easier for HTTP log parsers. The following bytes are escaped: - - ' (single quote) - " (double quote) - all bytes in the range of \x00-\x1F - -== SYNOPSIS - -Clogger may be loaded as Rack middleware in your config.ru: - - require "clogger" - use Clogger, - :format => Clogger::Format::Combined, - :logger => File.open("/path/to/log", "ab") - run YourApplication.new - -If you're using Rails 2.3.x or later, in your config/environment.rb -somewhere inside the "Rails::Initializer.run do |config|" block: - - config.middleware.use 'Clogger', - :format => Clogger::Format::Combined, - :logger => File.open("/path/to/log", "ab") - -== VARIABLES - -* $http_* - HTTP request headers (e.g. $http_user_agent) -* $sent_http_* - HTTP response headers (e.g. $sent_http_content_length) -* $content_length - HTTP request body size - ($http_content_length is not allowed by Rack) -* $content_type - HTTP request content type - ($http_content_type is not allowed by Rack) -* $cookie_* - HTTP request cookie (e.g. $cookie_session_id) - Rack::Request#cookies must have been used by the underlying application - to parse the cookies into a hash. -* $request_method - the HTTP request method (e.g. GET, POST, HEAD, ...) -* $path_info - path component requested (e.g. /index.html) -* $query_string - request query string (not including leading "?") -* $request_uri - the URI requested ($path_info?$query_string) -* $request - the first line of the HTTP request - ($request_method $request_uri $http_version) -* $request_time, $request_time{PRECISION} - time taken for request - (including response body iteration). PRECISION defaults to 3 - (milliseconds) if not specified but may be specified anywhere from - 0(seconds) to 6(microseconds). -* $time_local, $time_local{FORMAT} - current local time, FORMAT defaults to - "%d/%b/%Y:%H:%M:%S %z" but accepts any strftime(3)-compatible format -* $time_utc, $time_utc{FORMAT} - like $time_local, except with UTC -* $usec - current time in seconds.microseconds since the Epoch -* $msec - current time in seconds.milliseconds since the Epoch -* $body_bytes_sent - bytes in the response body (Apache: %B) -* $response_length - body_bytes_sent, except "-" instead of "0" (Apache: %b) -* $remote_user - HTTP-authenticated user -* $remote_addr - IP of the requesting client socket -* $ip - X-Forwarded-For request header if available, $remote_addr if not -* $pid - process ID of the current process -* $e{Thread.current} - Thread processing the request -* $e{Actor.current} - Actor processing the request (Revactor or Rubinius) - -== REQUIREMENTS - -* Ruby, Rack - -== DEVELOPMENT - -The latest development happens in git and is published to the following: - - git://git.bogomips.org/clogger.git - git://repo.or.cz/clogger.git - -You may also browse and download snapshot tarballs: - -* http://git.bogomips.org/cgit/clogger.git (cgit) -* http://repo.or.cz/w/clogger.git (gitweb) - -The mailing list (see below) is central for coordination and -development. Patches should always be sent inline -(git format-patch -M + git send-email) so we can reply to them inline. - -== CONTACT - -All feedback (bug reports, user/development dicussion, patches, pull -requests) go to the mailing list. - -* mailto:clogger@librelist.com - -Do not send HTML mail or attachments. Do not top post. - -== INSTALL - -For all Rubygems users: - - gem install clogger - -If you're using MRI 1.8/1.9 and have a build environment, you can also try: - - gem install clogger_ext - -If you do not use Rubygems, you may also use setup.rb from tarballs from -the Rubyforge project page: - -* http://rubyforge.org/frs/?group_id=8896 - -== LICENSE - -Copyright (C) 2009 Eric Wong and contributors. - -Clogger is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, version 3.0. - -Clogger is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with Clogger; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 diff --git a/Rakefile b/Rakefile index 0cc50a7..cdcded1 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,3 @@ -require 'hoe' -$LOAD_PATH << 'lib' -require 'clogger' begin require 'rake/extensiontask' Rake::ExtensionTask.new('clogger_ext') @@ -8,24 +5,33 @@ rescue LoadError warn "rake-compiler not available, cross compiling disabled" end -common = lambda do |hoe| - title = hoe.paragraphs_of("README.txt", 0).first.sub(/^= /, '') - hoe.version = Clogger::VERSION - hoe.summary = title.split(/\s*-\s*/, 2).last - hoe.description = hoe.paragraphs_of("README.txt", 3) - hoe.rubyforge_name = 'clogger' - hoe.author = 'Eric Wong' - hoe.email = 'clogger@librelist.com' - hoe.spec_extras.merge!('rdoc_options' => [ "--title", title ]) - hoe.remote_rdoc_dir = '' - hoe.extra_deps << [ 'rack', '> 0.9' ] +desc 'prints RDoc-formatted history' +task :history do + tags = `git tag -l`.split(/\n/).grep(/^v/).reverse + timefmt = '%Y-%m-%d %H:%M UTC' + tags.each do |tag| + header, subject, body = `git cat-file tag #{tag}`.split(/\n\n/) + tagger = header.split(/\n/).grep(/^tagger /).first.split(/\s/) + time = Time.at(tagger[-2].to_i).utc + puts "=== #{tag.sub(/^v/, '')} / #{time.strftime(timefmt)}" + puts "" + puts body + puts "" + end end -if ENV['CLOGGER_EXT'] - Hoe.spec('clogger_ext') do - common.call(self) - self.spec_extras.merge!(:extensions => Dir.glob('ext/*/extconf.rb')) - end -else - Hoe.spec('clogger') { common.call(self) } +desc "read news article from STDIN and post to rubyforge" +task :publish_news do + require 'rubyforge' + IO.select([STDIN], nil, nil, 1) or abort "E: news must be read from stdin" + msg = STDIN.readlines + subject = msg.shift + blank = msg.shift + blank == "\n" or abort "no newline after subject!" + subject.strip! + body = msg.join("").strip! + + rf = RubyForge.new.configure + rf.login + rf.post_news('clogger', subject, body) end diff --git a/clogger.gemspec b/clogger.gemspec new file mode 100644 index 0000000..0876b0a --- /dev/null +++ b/clogger.gemspec @@ -0,0 +1,30 @@ +ENV["VERSION"] or abort "VERSION= must be specified" + +Gem::Specification.new do |s| + s.name = %q{clogger} + s.version = ENV["VERSION"] + + if s.respond_to? :required_rubygems_version= + s.required_rubygems_version = Gem::Requirement.new(">= 0") + end + s.homepage = 'http://clogger.rubyforge.org/' + s.authors = ["Eric Wong"] + s.date = Time.now.utc.strftime('%Y-%m-%d') + s.description = %q{ +Clogger is Rack middleware for logging HTTP requests. The log format +is customizable so you can specify exactly which fields to log. +}.strip + s.email = %q{clogger@librelist.com} + s.extra_rdoc_files = %w(README History) + s.files = File.readlines('.manifest').map! { |x| x.chomp! } + s.rdoc_options = [ "-Na", + "-t", "Clogger - configurable request logging for Rack" + ] + s.require_paths = %w(lib ext) + s.rubyforge_project = %q{clogger} + s.summary = %q{configurable request logging for Rack} + s.test_files = %w(test/test_clogger.rb) + + # HeaderHash wasn't case-insensitive in old versions + s.add_dependency(%q, ["> 0.9"]) +end -- cgit v1.2.3-24-ge0c7