Skip to content
Browse files

Added proper logging and configuration

  • Loading branch information...
1 parent 0793735 commit bdaa25a080afc9a63b5d5543e9a93eb3a509883f @tobi committed
View
3 .gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+
+*.log
View
14 config.ru
@@ -2,20 +2,16 @@
require 'rubygems'
require 'rack/cache'
-require 'rubygems'
-require 'sinatra'
-require 'logger'
+require 'lib/middlewear/cache_purge'
+require 'lib/middlewear/logged_request'
require 'image_server'
-require 'lib/cache_purge'
-OriginServer = 'static.shopify.com'
-$logger = Logger.new(STDOUT)
+use LoggedRequest
use Rack::Cache,
- :verbose => true,
- :metastore => 'memcached://localhost:11211/meta',
- :entitystore => 'file:/tmp/cache/rack/body'
+ :metastore => ENV['META_STORE'],
+ :entitystore => ENV['ENTITY_STORE']
use CachePurge
View
19 config/environment.rb
@@ -0,0 +1,19 @@
+# Image server configuration file
+
+RACK_ENV = ENV['RACK_ENV'] || 'development'
+
+
+# Upstream Server where the assets live
+
+ORIGIN_SERVER = ENV['ORIGIN_SERVER'] || 'static.shopify.com'
+
+
+# Middlewear configuration
+# recommended to be memcached for meta and disk for entities.
+
+ENV['META_STORE'] = 'memcached://localhost:11211/meta'
+ENV['ENTITY_STORE'] = 'file:/tmp/cache/rack/body'
+
+
+# Logging
+Logger.current = RequestAwareLogger.new("log/#{RACK_ENV}.log")
View
29 image_server.rb
@@ -1,22 +1,24 @@
-require 'rubygems'
+require 'lib/logger_ext'
require 'lib/transformations'
require 'lib/image'
require 'lib/remote_image'
+require 'config/environment'
+
class ImageServer
- NotFound = [404, {'Content-Type' => 'text/html'}, ['<h1>File not Found</h1>']]
+ NotFound = [404, {'Content-Type' => 'text/html'}, ['<h1>File not Found</h1>']].freeze
+
+ def initialze(options = {})
+ @options = options
+ end
-
def call(env)
-
request = Rack::Request.new(env)
- requested_file = RemoteImage.new(OriginServer, request.path, request.query_string)
+ requested_file = RemoteImage.new(ORIGIN_SERVER, request.path, request.query_string)
- # If file exists we simply sent it to the client.
+ # If file exists we simply sent it to the client.
if requested_file.download
-
- $logger.info 'Hit: Direct'
return requested_file.to_response
@@ -24,19 +26,14 @@ def call(env)
# go look for the original image and resize it according to the request.
elsif requested_file.image? && requested_file.variant?
- origin_file = RemoteImage.new(OriginServer, requested_file.find_original_path, request.query_string)
+ origin_file = RemoteImage.new(ORIGIN_SERVER, requested_file.find_original_path, request.query_string)
if origin_file.download
origin_file.transform_content!(requested_file.variant)
- $logger.info "Hit: Origin, transformed:#{requested_file.variant}"
-
return origin_file.to_response
- else
- $logger.info 'Miss, original'
end
- else
- $logger.info 'Miss, requested'
end
- NotFound
+
+ NotFound
end
end
View
16 lib/image.rb
@@ -2,7 +2,6 @@
require 'fileutils'
class Image
- VARIANT_DELIMITER = '_'
attr_accessor :content
attr_accessor :content_type
@@ -24,7 +23,7 @@ def ext
def dirname
File.dirname(@path)
- end
+ end
# Returns true if the file is of a image type
def image?
@@ -42,10 +41,13 @@ def cache_control
def transform_content!(variant)
img = Magick::Image.from_blob(@content).first
transformation = Transformations[variant]
- raise ArgumentError, "#{variant} is not a known transformation. (#{Transformations.list.join(', ')})" if transformation.nil?
- img = transformation.call(img)
- raise ArgumentError, "Creating variant #{variant} for #{path} produced an error. Please return a Magick::Image" if img.nil?
- self.content = img.to_blob
+
+ Logger.current.info_with_time "Transforming image to #{variant}" do
+ raise ArgumentError, "#{variant} is not a known transformation. (#{Transformations.list.join(', ')})" if transformation.nil?
+ img = transformation.call(img)
+ raise ArgumentError, "Creating variant #{variant} for #{path} produced an error. Please return a Magick::Image" if img.nil?
+ self.content = img.to_blob
+ end
true
end
@@ -58,7 +60,7 @@ def variant?
end
def to_response
- [200, {'Content-Type' => content_type, 'Content-Length' => content.length.to_s, 'Cache-Control' => cache_control}, [content]]
+ [200, {'Content-Type' => content_type, 'Cache-Control' => cache_control}, [content]]
end
# Reverse the filename to find the original image from which we can generate the desired
View
41 lib/logger_ext.rb
@@ -0,0 +1,41 @@
+require 'logger'
+require 'benchmark'
+
+class Logger
+
+ def self.current
+ @logger
+ end
+
+ def self.current=(logger)
+ @logger = logger
+ end
+
+end
+
+class RequestAwareLogger < Logger
+
+
+ def intend
+ @intend = true
+ yield
+ ensure
+ @intend = false
+ end
+
+
+ def info_with_time(msg)
+ result = nil
+ rm = Benchmark.realtime { result = yield }
+ info msg + " [%.3fs]" % [rm]
+ result
+ end
+
+ [:info, :warn, :error].each do |level|
+ define_method(level) do |msg|
+ @intend ? super(" " + msg) : super
+ end
+ end
+
+
+end
View
0 lib/cache_purge.rb → lib/middlewear/cache_purge.rb
File renamed without changes.
View
26 lib/middlewear/logged_request.rb
@@ -0,0 +1,26 @@
+
+class LoggedRequest
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+
+ request = Rack::Cache::Request.new(env)
+
+ resp = nil
+
+ Logger.current.info "#{request.request_method} #{request.path} [#{request.ip}]"
+
+ secs = Benchmark.realtime do
+ Logger.current.intend do
+ resp = @app.call(env)
+ end
+ end
+
+ Logger.current.info((resp[0] == 200 ? 'Success' : "Error [#{resp[0]}]") + " after %.3fs Cache: %s" % [secs, resp[1]['X-Rack-Cache']])
+
+ resp
+ end
+end
View
7 lib/remote_image.rb
@@ -21,8 +21,9 @@ def content_type
def download(path = path)
query_path = query_string.empty? ? path : "#{path}?#{query_string}"
- $logger.info "Loading http://#{@server + query_path}"
- response = Net::HTTP.get_response(@server, query_path)
+ response = Logger.current.info_with_time "Loading http://#{@server + query_path}" do
+ Net::HTTP.get_response(@server, query_path)
+ end
@headers = response
@status = response.code.to_i
@@ -31,7 +32,7 @@ def download(path = path)
self.content = response.body
true
else
- $logger.error "Not found"
+ Logger.current.error "Not found"
false
end
end
View
3 lib/transformations.rb
@@ -13,8 +13,7 @@ def self.[](name)
def self.register(name, &block)
@transformations[name.to_s] = Proc.new(&block)
- end
-
+ end
end

0 comments on commit bdaa25a

Please sign in to comment.
Something went wrong with that request. Please try again.