Merge branch 'heroku_fixes'

This commit is contained in:
Maxwell Salzberg 2012-01-05 17:31:49 -08:00
commit 646981aa17
13 changed files with 268 additions and 170 deletions

1
.gitignore vendored
View file

@ -13,7 +13,6 @@ config/oauth_keys.yml
config/initializers/secret_token.rb
config/redis.conf
config/deploy_config.yml
config/newrelic.yml
.bundle
vendor/bundle/*
vendor/cache/*

View file

@ -23,7 +23,6 @@ gem 'omniauth-twitter'
gem 'twitter', '2.0.2'
# backups
gem 'cloudfiles', '1.4.10', :require => false
# mail
gem 'messagebus_ruby_api', '1.0.1'

View file

@ -130,8 +130,6 @@ GEM
ffi (~> 1.0.6)
chronic (0.6.6)
client_side_validations (3.1.3)
cloudfiles (1.4.10)
mime-types (>= 1.16)
columnize (0.3.5)
crack (0.3.1)
cucumber (1.1.3)
@ -461,7 +459,6 @@ DEPENDENCIES
carrierwave (= 0.5.8)
chef (~> 0.10.4)
client_side_validations
cloudfiles (= 1.4.10)
cucumber-api-steps (= 0.6)
cucumber-rails (= 1.2.1)
database_cleaner (= 0.7.0)

View file

@ -1,6 +1,7 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require 'uri'
require File.join(Rails.root, 'lib', 'enviroment_configuration')
@ -67,7 +68,9 @@ Please do the following:
HELP
Process.exit(1)
end
end
def self.setup!
normalize_pod_url
normalize_admins
normalize_pod_services

View file

@ -96,8 +96,20 @@ defaults: &defaults
# Hoptoad api key, send failures to Hoptoad
hoptoad_api_key: ''
#social media setup
facebook_app_id: ''
facebook_app_secret: ''
twitter_consumer_key: ''
twitter_consumer_secret: ''
tumblr_consumer_key: ''
tumblr_consumer_secret: ''
# Miscellaneous
NEW_RELIC_LICENSE_KEY: ''
# If set to true Diaspora will work with just the appserver, thin by default,
# running, however this makes it quite slow as all the time intensive jobs
# must be run inside the request cycle. Also the live updates from the Websocket

View file

@ -19,7 +19,7 @@ Diaspora::Application.configure do
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
config.active_support.deprecation = :log
config.active_support.deprecation = [:stderr, :log]
#config.threadsafe!
# Monkeypatch around the nasty "2.5MB exception page" issue, caused by very large environment vars
# This snippet via: http://stackoverflow.com/questions/3114993/exception-pages-in-development-mode-take-upwards-of-15-30-seconds-to-render-why

View file

@ -0,0 +1,18 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
def load_config_yaml filename
YAML.load(ERB.new(File.read(filename)).result)
end
oauth_keys_file = "#{Rails.root}/config/oauth_keys.yml"
SERVICES = load_config_yaml("#{oauth_keys_file}.example")
#this is to be backwards compatible with current production setups
if File.exist? oauth_keys_file
ActiveSupport::Deprecation.warn("01/05/2012 keys in oauth_keys.yml should be moved into application.yml. SEE application.yml.example for updated key names")
SERVICES.deep_merge!(load_config_yaml(oauth_keys_file))
end

View file

@ -0,0 +1 @@
AppConfig.setup!

View file

@ -1,18 +0,0 @@
# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
def load_config_yaml filename
YAML.load(File.read(filename))
end
oauth_keys_file = "#{Rails.root}/config/oauth_keys.yml"
SERVICES = nil
silence_warnings do
SERVICES = load_config_yaml("#{oauth_keys_file}.example")
if File.exist? oauth_keys_file
SERVICES.deep_merge!(load_config_yaml(oauth_keys_file))
end
end

227
config/newrelic.yml Normal file
View file

@ -0,0 +1,227 @@
#
# This file configures the New Relic Agent. New Relic monitors
# Ruby, Java, .NET, PHP, and Python applications with deep visibility and low overhead.
# For more information, visit www.newrelic.com.
#
# Generated January 05, 2012
#
# This configuration file is custom generated for Diaspora, Inc.
# Here are the settings that are common to all environments:
common: &default_settings
# ============================== LICENSE KEY ===============================
# You must specify the license key associated with your New Relic
# account. This key binds your Agent's data to your account in the
# New Relic service.
license_key: <%= AppConfig['NEW_RELIC_LICENSE_KEY'] %>
# Agent Enabled (Ruby/Rails Only)
# Use this setting to force the agent to run or not run.
# Default is 'auto' which means the agent will install and run only
# if a valid dispatcher such as Mongrel is running. This prevents
# it from running with Rake or the console. Set to false to
# completely turn the agent off regardless of the other settings.
# Valid values are true, false and auto.
# agent_enabled: auto
# Application Name
# Set this to be the name of your application as you'd like it show
# up in New Relic. New Relic will then auto-map instances of your application
# into a New Relic "application" on your home dashboard page. If you want
# to map this instance into multiple apps, like "AJAX Requests" and
# "All UI" then specify a semicolon-separated list of up to three
# distinct names. If you comment this out, it defaults to the
# capitalized RAILS_ENV (i.e., Production, Staging, etc)
app_name: <%= AppConfig[:pod_uri].host%>
# When "true", the agent collects performance data about your
# application and reports this data to the New Relic service at
# newrelic.com. This global switch is normally overridden for each
# environment below. (formerly called 'enabled')
monitor_mode: true
# Developer mode should be off in every environment but
# development as it has very high overhead in memory.
developer_mode: false
# The newrelic agent generates its own log file to keep its logging
# information separate from that of your application. Specify its
# log level here.
log_level: info
# The newrelic agent communicates with the New Relic service via http by
# default. If you want to communicate via https to increase
# security, then turn on SSL by setting this value to true. Note,
# this will result in increased CPU overhead to perform the
# encryption involved in SSL communication, but this work is done
# asynchronously to the threads that process your application code,
# so it should not impact response times.
ssl: true
# EXPERIMENTAL: enable verification of the SSL certificate sent by
# the server. This setting has no effect unless SSL is enabled
# above. This may block your application. Only enable it if the data
# you send us needs end-to-end verified certificates.
#
# This means we cannot cache the DNS lookup, so each request to the
# New Relic service will perform a lookup. It also means that we cannot
# use a non-blocking lookup, so in a worst case, if you have DNS
# problems, your app may block indefinitely.
# verify_certificate: true
# Set your application's Apdex threshold value with the 'apdex_t'
# setting, in seconds. The apdex_t value determines the buckets used
# to compute your overall Apdex score.
# Requests that take less than apdex_t seconds to process will be
# classified as Satisfying transactions; more than apdex_t seconds
# as Tolerating transactions; and more than four times the apdex_t
# value as Frustrating transactions.
# For more about the Apdex standard, see
# http://newrelic.com/docs/general/apdex
apdex_t: 0.5
# Proxy settings for connecting to the New Relic server.
#
# If a proxy is used, the host setting is required. Other settings
# are optional. Default port is 8080.
#
# proxy_host: hostname
# proxy_port: 8080
# proxy_user:
# proxy_pass:
# Tells transaction tracer and error collector (when enabled)
# whether or not to capture HTTP params. When true, frameworks can
# exclude HTTP parameters from being captured.
# Rails: the RoR filter_parameter_logging excludes parameters
# Java: create a config setting called "ignored_params" and set it to
# a comma separated list of HTTP parameter names.
# ex: ignored_params: credit_card, ssn, password
capture_params: false
# Transaction tracer captures deep information about slow
# transactions and sends this to the New Relic service once a
# minute. Included in the transaction is the exact call sequence of
# the transactions including any SQL statements issued.
transaction_tracer:
# Transaction tracer is enabled by default. Set this to false to
# turn it off. This feature is only available at the Professional
# product level.
enabled: true
# Threshold in seconds for when to collect a transaction
# trace. When the response time of a controller action exceeds
# this threshold, a transaction trace will be recorded and sent to
# New Relic. Valid values are any float value, or (default) "apdex_f",
# which will use the threshold for an dissatisfying Apdex
# controller action - four times the Apdex T value.
transaction_threshold: apdex_f
# When transaction tracer is on, SQL statements can optionally be
# recorded. The recorder has three modes, "off" which sends no
# SQL, "raw" which sends the SQL statement in its original form,
# and "obfuscated", which strips out numeric and string literals.
record_sql: obfuscated
# Threshold in seconds for when to collect stack trace for a SQL
# call. In other words, when SQL statements exceed this threshold,
# then capture and send to New Relic the current stack trace. This is
# helpful for pinpointing where long SQL calls originate from.
stack_trace_threshold: 0.500
# Determines whether the agent will capture query plans for slow
# SQL queries. Only supported in mysql and postgres. Should be
# set to false when using other adapters.
# explain_enabled: true
# Threshold for query execution time below which query plans will not
# not be captured. Relevant only when `explain_enabled` is true.
# explain_threshold: 0.5
# Error collector captures information about uncaught exceptions and
# sends them to New Relic for viewing
error_collector:
# Error collector is enabled by default. Set this to false to turn
# it off. This feature is only available at the Professional
# product level.
enabled: true
# Rails Only - tells error collector whether or not to capture a
# source snippet around the place of the error when errors are View
# related.
capture_source: true
# To stop specific errors from reporting to New Relic, set this property
# to comma-separated values. Default is to ignore routing errors,
# which are how 404's get triggered.
ignore_errors: ActionController::RoutingError
# (Advanced) Uncomment this to ensure the CPU and memory samplers
# won't run. Useful when you are using the agent to monitor an
# external resource
# disable_samplers: true
# If you aren't interested in visibility in these areas, you can
# disable the instrumentation to reduce overhead.
#
# disable_view_instrumentation: true
# disable_activerecord_instrumentation: true
# disable_memcache_instrumentation: true
# disable_dj: true
# Certain types of instrumentation such as GC stats will not work if
# you are running multi-threaded. Please let us know.
# multi_threaded = false
# Application Environments
# ------------------------------------------
# Environment-specific settings are in this section.
# For Rails applications, RAILS_ENV is used to determine the environment.
# For Java applications, pass -Dnewrelic.environment <environment> to set
# the environment.
# NOTE if your application has other named environments, you should
# provide newrelic configuration settings for these environments here.
development:
<<: *default_settings
# Turn off communication to New Relic service in development mode (also
# 'enabled').
# NOTE: for initial evaluation purposes, you may want to temporarily
# turn agent communication on in development mode.
monitor_mode: false
# Rails Only - when running in Developer Mode, the New Relic Agent will
# present performance information on the last 100 transactions you have
# executed since starting the app server.
# NOTE: There is substantial overhead when running in developer mode.
# Do not use for production or load testing.
developer_mode: true
# Enable textmate links
# textmate: true
test:
<<: *default_settings
# It almost never makes sense to turn on the agent when running
# unit, functional or integration tests or the like.
monitor_mode: false
# Turn on the agent in production for 24x7 monitoring. New Relic
# testing shows an average performance impact of < 5 ms per
# transaction, so you can leave this on all the time without
# incurring any user-visible performance degradation.
production:
<<: *default_settings
monitor_mode: true
# Many applications have a staging environment which behaves
# identically to production. Support for that environment is provided
# here. By default, the staging environment has the agent turned on.
staging:
<<: *default_settings
monitor_mode: true
app_name: My Application (Staging)

View file

@ -1,9 +1,9 @@
twitter:
consumer_key: ""
consumer_secret: ""
consumer_key: <%= AppConfig['twitter_consumer_key'] %>
consumer_secret: <%= AppConfig['twitter_consumer_secret'] %>
facebook:
app_id: ""
app_secret: ""
app_id: <%=AppConfig['facebook_app_id'] %>
app_secret: <%= AppConfig['facebook_app_secret'] %>
tumblr:
consumer_key: ""
consumer_secret: ""
consumer_key: <%= AppConfig['tumblr_consumer_key'] %>
consumer_secret: <%= AppConfig['tumblr_consumer_secret'] %>

View file

@ -1,140 +0,0 @@
namespace :backup do
desc "Backup Tasks"
require File.join(Rails.root, 'config', 'initializers', '_load_app_config.rb')
require 'cloudfiles'
require 'fileutils'
tmp_backup_dir = "./tmp/backup"
tmp_sql_file = "backup.sql"
tmp_db_dir = "db"
task :all => [:database, :photos]
task :mysql => [:database]
task :postgresql => [:database]
task :database do
puts("event=backup status=start type=database")
tmp_pass_file = ".pgpass.conf.tmp"
db = YAML::load(File.open(File.join(File.dirname(__FILE__), '..','..', 'config', 'database.yml')))
host = db['production']['host']
port = db['production']['port'].to_s
user = db['production']['username']
password = db['production']['password']
database = db['production']['database']
unless AppConfig[:cloudfiles_username] && AppConfig[:cloudfiles_api_key] && AppConfig[:cloudfiles_db_container] &&
AppConfig[:backup_retention_days] && !user.blank?
puts "Cloudfiles username needed" unless AppConfig[:cloudfiles_username]
puts "Cloudfiles api_key needed" unless AppConfig[:cloudfiles_api_key]
puts "Cloudfiles database container needed" unless AppConfig[:cloudfiles_db_container]
puts "Retention period needed" unless AppConfig[:backup_retention_days]
puts "Database auth data needed" if user.blank?
Process.exit
end
puts "Logging into Cloud Files"
cf = CloudFiles::Connection.new(:username => AppConfig[:cloudfiles_username], :api_key => AppConfig[:cloudfiles_api_key])
FileUtils.mkdir_p(tmp_backup_dir + "/" + tmp_db_dir)
container = cf.container(AppConfig[:cloudfiles_db_container])
if db['production']['adapter'] == 'postgresql'
file = File.new(tmp_backup_dir + "/" + tmp_pass_file, 'w')
file.chmod( 0600 )
file.write(host + ":" +
port + ":" +
database + ":" +
user + ":" +
password + "\n")
file.close
puts "Dumping PostgreSQL at #{Time.now.to_s}"
`PGPASSFILE=#{tmp_backup_dir}/#{tmp_pass_file} nice pg_dump -h #{host} -p #{port} -U #{user} #{database} > #{tmp_backup_dir}/#{tmp_db_dir}/#{tmp_sql_file} `
File.delete(tmp_backup_dir + "/" + tmp_pass_file)
puts "Gzipping dump at #{Time.now.to_s}"
tar_name = "postgresql_#{Time.now.to_i}.tar"
`nice tar cfPz #{tmp_backup_dir}/#{tar_name} #{tmp_backup_dir}/#{tmp_db_dir}`
elsif db['production']['adapter'] == 'mysql2'
puts "Dumping Mysql at #{Time.now.to_s}"
`nice mysqldump --single-transaction --quick --user=#{user} --password=#{password} #{database} > #{tmp_backup_dir}/#{tmp_db_dir}/#{tmp_sql_file} `
puts "Gzipping dump at #{Time.now.to_s}"
tar_name = "mysql_#{Time.now.to_i}.tar"
`nice tar cfPz #{tmp_backup_dir}/#{tar_name} #{tmp_backup_dir}/#{tmp_db_dir}`
end
file = container.create_object(tar_name)
puts "Uploading archive at #{Time.now.to_s}"
if file.write File.open(tmp_backup_dir + "/" + tar_name)
puts("event=backup status=success type=database")
File.delete(tmp_backup_dir + "/" + tar_name)
File.delete(tmp_backup_dir + "/" + tmp_db_dir + "/" + tmp_sql_file)
Dir.delete(tmp_backup_dir + "/" + tmp_db_dir)
Dir.delete(tmp_backup_dir)
puts("Deleting Cloud Files objects that are older than specified retention period")
files = container.objects
files.each do |file|
object = container.object(file)
if object.last_modified < (Time.now - (AppConfig[:backup_retention_days] * 24 * 60 * 60))
puts("Deleting expired Cloud Files object: " + file)
container.delete_object(file)
end
end
else
puts("event=backup status=failure type=database")
end
end
task :photos do
puts("event=backup status=start type=photos")
if AppConfig[:cloudfiles_username] && AppConfig[:cloudfiles_api_key] && AppConfig[:cloudfiles_images_container]
puts "Logging into Cloud Files"
cf = CloudFiles::Connection.new(:username => AppConfig[:cloudfiles_username], :api_key => AppConfig[:cloudfiles_api_key])
container = cf.container(AppConfig[:cloudfiles_images_container])
images_dir = File.join(File.dirname(__FILE__), '..', '..', 'public/uploads/images/')
FileUtils.mkdir_p(tmp_backup_dir)
tar_name = "photos_#{Time.now.to_i}.tar"
`tar cfPz /dev/stdout #{images_dir} | split -d -b 4831838208 - #{tmp_backup_dir}/#{tar_name}`
(0..99).each do |n|
padded_str = n.to_s.rjust(2,'0')
file = container.create_object(tar_name + padded_str)
file_path = tmp_backup_dir + "/" + tar_name + padded_str
if File.exists?(file_path)
if file.write File.open(file_path)
puts("event=backup status=success type=photos")
else
puts("event=backup status=failure type=photos")
end
File.delete(file_path)
end
end
Dir.delete(tmp_backup_dir)
puts("Deleting Cloud Files objects that are older than specified retention period")
files = container.objects
files.each do |file|
object = container.object(file)
if object.last_modified < (Time.now - (AppConfig[:backup_retention_days] * 24 * 60 * 60))
puts("Deleting expired Cloud Files object: " + file)
container.delete_object(file)
end
end
else
puts "Cloudfiles username and api key needed"
end
end
end