forked from e621ng/e621ng
[Prod] Add Datadog
Let's see how this one works out. Cute logo
This commit is contained in:
parent
40ff649250
commit
0b47770c49
14
.env.sample
14
.env.sample
@ -50,7 +50,9 @@
|
||||
# The application must have its OAuth2 redirect URI set to ${JOINER_BASE_URL}/callback.
|
||||
# You also need to fill out all the JOINER_* environment variables below.
|
||||
#
|
||||
# COMPOSE_PROFILES=discord
|
||||
# datadog: Start the datadog agent to push performance metrics through ddtrace.
|
||||
# You also need to fill out the DD_API_KEY environment variables below.
|
||||
# COMPOSE_PROFILES=discord,datadog
|
||||
|
||||
# Change the ports that are forwarded by docker to avoid potential conflicts
|
||||
|
||||
@ -64,3 +66,13 @@
|
||||
# JOINER_OAUTH2_CLIENT_SECRET=
|
||||
# JOINER_GUILD_ID=
|
||||
# JOINER_FAILED_JOIN_WEBHOOK_URL=
|
||||
|
||||
# The following environment variables are used when using the 'datadog' profile:
|
||||
|
||||
# Required:
|
||||
# DD_API_KEY=
|
||||
#
|
||||
# Optional:
|
||||
# DD_SITE=us5.datadoghq.com
|
||||
# DD_SERVICE=E6ng (Dev)
|
||||
# DD_ENV=local
|
||||
|
2
Gemfile
2
Gemfile
@ -35,6 +35,8 @@ gem "rugged"
|
||||
# Blocked by unicorn which lacks a release with Rack 3 support
|
||||
gem "rack", "~> 2.0"
|
||||
|
||||
gem "datadog", require: "datadog/auto_instrument"
|
||||
|
||||
gem 'opensearch-ruby'
|
||||
|
||||
gem 'mailgun-ruby'
|
||||
|
11
Gemfile.lock
11
Gemfile.lock
@ -115,7 +115,14 @@ GEM
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
dalli (3.2.6)
|
||||
datadog (2.0.0.beta1)
|
||||
base64
|
||||
debase-ruby_core_source (= 3.3.1)
|
||||
libdatadog (~> 6.0.0.2.0)
|
||||
libddwaf (~> 1.14.0.0.0)
|
||||
msgpack
|
||||
date (3.3.4)
|
||||
debase-ruby_core_source (3.3.1)
|
||||
debug (1.9.1)
|
||||
irb (~> 1.10)
|
||||
reline (>= 0.3.8)
|
||||
@ -163,6 +170,9 @@ GEM
|
||||
jsonapi-renderer (0.2.2)
|
||||
kgio (2.11.4)
|
||||
language_server-protocol (3.17.0.3)
|
||||
libdatadog (6.0.0.2.0)
|
||||
libddwaf (1.14.0.0.0)
|
||||
ffi (~> 1.0)
|
||||
listen (3.8.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
@ -380,6 +390,7 @@ DEPENDENCIES
|
||||
bcrypt
|
||||
bootsnap
|
||||
dalli
|
||||
datadog
|
||||
debug
|
||||
diffy
|
||||
dotenv
|
||||
|
@ -1,20 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DanbooruLogger
|
||||
def self.log(exception, expected: false, **_params)
|
||||
def self.log(exception, expected: false)
|
||||
if expected
|
||||
Rails.logger.info("#{exception.class}: #{exception.message}")
|
||||
else
|
||||
backtrace = Rails.backtrace_cleaner.clean(exception.backtrace).join("\n")
|
||||
Rails.logger.error("#{exception.class}: #{exception.message}\n#{backtrace}")
|
||||
end
|
||||
|
||||
Datadog::Tracing.active_span&.set_error(exception) unless expected
|
||||
end
|
||||
|
||||
def self.initialize(user)
|
||||
add_attributes("user.id" => user.id, "user.name" => user.name)
|
||||
add_attributes("user.id" => user.id) unless user.is_anonymous?
|
||||
end
|
||||
|
||||
def self.add_attributes(**)
|
||||
# noop
|
||||
Datadog::Tracing.active_span&.set_tags(**)
|
||||
end
|
||||
end
|
||||
|
@ -217,8 +217,7 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
def with_timeout(n, default_value = nil)
|
||||
connection.execute("SET STATEMENT_TIMEOUT = #{n}") unless Rails.env == "test"
|
||||
yield
|
||||
rescue ::ActiveRecord::StatementInvalid => x
|
||||
DanbooruLogger.log(x, expected: true)
|
||||
rescue ::ActiveRecord::StatementInvalid
|
||||
return default_value
|
||||
ensure
|
||||
connection.execute("SET STATEMENT_TIMEOUT = #{CurrentUser.user.try(:statement_timeout) || 3_000}") unless Rails.env == "test"
|
||||
|
@ -206,8 +206,6 @@ class TagAlias < TagRelationship
|
||||
forum_updater.update(failure_message(e), "FAILED") if update_topic
|
||||
update_columns(status: "error: #{e}")
|
||||
end
|
||||
|
||||
DanbooruLogger.log(e, tag_alias_id: id, antecedent_name: antecedent_name, consequent_name: consequent_name)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -138,8 +138,6 @@ class TagImplication < TagRelationship
|
||||
|
||||
forum_updater.update(failure_message(e), "FAILED") if update_topic
|
||||
update_columns(status: "error: #{e}")
|
||||
|
||||
DanbooruLogger.log(e, tag_implication_id: id, antecedent_name: antecedent_name, consequent_name: consequent_name)
|
||||
end
|
||||
end
|
||||
|
||||
|
10
config/initializers/01_sensitive_params.rb
Normal file
10
config/initializers/01_sensitive_params.rb
Normal file
@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SensitiveParams
|
||||
# Common values for Rails and Datadog query parameter filtering
|
||||
PARAMS = %i[passw secret token _key crypt salt certificate otp ssn email].freeze
|
||||
|
||||
def self.to_datadog_regex
|
||||
Regexp.new("(?:#{PARAMS.join('|')})[^&]*=[^&]*")
|
||||
end
|
||||
end
|
14
config/initializers/datadog.rb
Normal file
14
config/initializers/datadog.rb
Normal file
@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Datadog.configure do |c|
|
||||
c.tracing.enabled = !Rails.env.test? && ENV["DD_API_KEY"].present?
|
||||
c.logger.level = Logger::WARN
|
||||
|
||||
c.tracing.instrument :rack, quantize: {
|
||||
query: {
|
||||
obfuscate: {
|
||||
regex: SensitiveParams.to_datadog_regex,
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
@ -5,6 +5,4 @@
|
||||
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
|
||||
# Use this to limit dissemination of sensitive information.
|
||||
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
|
||||
Rails.application.config.filter_parameters += [
|
||||
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :email
|
||||
]
|
||||
Rails.application.config.filter_parameters += SensitiveParams::PARAMS
|
||||
|
@ -15,6 +15,7 @@ x-environment: &common-env
|
||||
SESSION_SECRET_KEY: 44b4f44e9f253c406cbe727d403d500c1cecff943e4d2aea8f5447f28846fffe
|
||||
# Hide annoying output from libvips on corrupt files
|
||||
VIPS_WARNING: "0"
|
||||
DD_TRACE_STARTUP_LOGS: false
|
||||
|
||||
x-depends-on: &common-depends-on
|
||||
opensearch:
|
||||
@ -43,6 +44,9 @@ services:
|
||||
environment:
|
||||
<<: *common-env
|
||||
RAILS_ENV: development
|
||||
DD_AGENT_HOST: datadog-agent
|
||||
DD_SERVICE: ${DD_SERVICE:-}
|
||||
DD_ENV: ${DD_ENV:-}
|
||||
depends_on:
|
||||
<<: *common-depends-on
|
||||
autocompleted:
|
||||
@ -119,6 +123,17 @@ services:
|
||||
volumes:
|
||||
- iqdb_data:/iqdb
|
||||
|
||||
datadog-agent:
|
||||
image: datadog/agent:7.52.0
|
||||
environment:
|
||||
DD_API_KEY: ${DD_API_KEY:-}
|
||||
DD_SITE: ${DD_SITE:-us5.datadoghq.com}
|
||||
DD_HOSTNAME: datadog-agent
|
||||
DD_LOG_LEVEL: WARN
|
||||
DD_APM_NON_LOCAL_TRAFFIC: true
|
||||
profiles:
|
||||
- datadog
|
||||
|
||||
# Discord integration
|
||||
|
||||
discord_joiner:
|
||||
|
25
test/unit/datadog_test.rb
Normal file
25
test/unit/datadog_test.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "test_helper"
|
||||
|
||||
class DatadogTest < ActiveSupport::TestCase
|
||||
def assert_match_group(expected, query)
|
||||
assert_equal(expected, query[SensitiveParams.to_datadog_regex])
|
||||
end
|
||||
|
||||
def assert_no_match_group(query)
|
||||
assert_nil(query[SensitiveParams.to_datadog_regex])
|
||||
end
|
||||
|
||||
should "filters query parameters" do
|
||||
assert_match_group("password=hunter2", "password=hunter2")
|
||||
assert_match_group("password=hunter2", "?abc=def&password=hunter2&foo=bar")
|
||||
# These partial matches are fine, just don't let datadog grab it
|
||||
assert_match_group("password]=hunter2", "?abc=def&user[password]=hunter2&foo=bar")
|
||||
assert_match_group("password=hunter2", "old_password=hunter2")
|
||||
assert_match_group("password_old=hunter2", "password_old=hunter2")
|
||||
|
||||
assert_no_match_group("something=else")
|
||||
assert_no_match_group("search[foo]=bar")
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user