use inst_statsd

fixes CORE-2538

test plan
 - configure statsd to use data dog
 - it should work

Change-Id: Ie8428e4e99973b35506bd7a8e4d1a18f5a7875a1
Reviewed-on: https://gerrit.instructure.com/182083
Tested-by: Jenkins
Reviewed-by: Cody Cutrer <cody@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Rob Orton 2019-03-20 17:52:40 -06:00
parent 22dcf2430a
commit 04e7bf8cb8
35 changed files with 219 additions and 141 deletions

View File

@ -125,8 +125,10 @@ gem 'useragent', '0.16.10', require: false
gem 'crocodoc-ruby', '0.0.1', require: false
gem 'sentry-raven', '2.7.2', require: false
gem 'canvas_statsd', '2.0.4'
gem 'inst_statsd', '2.1.4'
gem 'statsd-ruby', '1.4.0', require: false
gem 'aroi', '0.0.6', require: false
gem 'dogstatsd-ruby', '3.3.0'
gem 'gepub', '1.0.1'
gem 'imperium', '0.5.0', require: false
gem 'academic_benchmarks', '0.0.10', require: false
@ -178,4 +180,3 @@ gem 'twitter', path: 'gems/twitter'
gem 'vericite_api', '1.5.3'
gem 'utf8_cleaner', path: 'gems/utf8_cleaner'
gem 'workflow', path: 'gems/workflow'
gem 'dogstatsd-ruby', '3.3.0'

View File

@ -463,21 +463,17 @@ class ApplicationController < ActionController::Base
end
def batch_statsd(&block)
CanvasStatsd::Statsd.batch(&block)
InstStatsd::Statsd.batch(&block)
end
def report_to_datadog(&block)
if (metric = params[:datadog_metric]) && metric.present?
require 'datadog/statsd'
datadog = Datadog::Statsd.new('localhost', 8125)
datadog.batch do |statsd|
tags = [
"domain:#{request.host_with_port.sub(':', '_')}",
"action:#{controller_name}.#{action_name}",
]
statsd.increment("graphql.rest_comparison.#{metric}.count", tags: tags)
statsd.time("graphql.rest_comparison.#{metric}.time", tags: tags, &block)
end
tags = {
domain: request.host_with_port.sub(':', '_'),
action: "#{controller_name}.#{action_name}",
}
InstStatsd::Statsd.increment("graphql.rest_comparison.#{metric}.count", tags: tags)
InstStatsd::Statsd.time("graphql.rest_comparison.#{metric}.time", tags: tags, &block)
else
yield
end

View File

@ -26,7 +26,6 @@ class Login::SamlController < ApplicationController
before_action :fix_ms_office_redirects, only: :new
def new
increment_saml_stat("login_attempt")
redirect_to delegated_auth_redirect_uri(aac.generate_authn_request_redirect(host: request.host_with_port,
parent_registration: session[:parent_registration],
relay_state: Rails.env.development? && params[:RelayState]))
@ -38,8 +37,6 @@ class Login::SamlController < ApplicationController
response, relay_state = SAML2::Bindings::HTTP_POST.decode(request.request_parameters)
increment_saml_stat('login_response_received')
aac = @domain_root_account.authentication_providers.active.
where(auth_type: 'saml').
where(idp_entity_id: response.issuer&.id).
@ -95,7 +92,6 @@ class Login::SamlController < ApplicationController
logger.info "Attempting SAML2 login for #{aac.login_attribute} #{unique_id} in account #{@domain_root_account.id}"
unless response.errors.empty?
increment_saml_stat("errors.invalid_response")
if debugging
aac.debug_set(:is_valid_login_response, 'false')
aac.debug_set(:login_response_validation_error, response.errors.join("\n"))
@ -136,7 +132,6 @@ class Login::SamlController < ApplicationController
aac.debug_set(:login_to_canvas_success, 'true')
aac.debug_set(:logged_in_user_id, user.id)
end
increment_saml_stat("normal.login_success")
session[:saml_unique_id] = unique_id
session[:name_id] = subject_name_id&.id
@ -168,7 +163,6 @@ class Login::SamlController < ApplicationController
successful_login(user, pseudonym)
else
unknown_user_url = @domain_root_account.unknown_user_url.presence || login_url
increment_saml_stat("errors.unknown_user")
message = "Received SAML login request for unknown user: #{unique_id} redirecting to: #{unknown_user_url}."
logger.warn message
aac.debug_set(:canvas_login_fail_message, message) if debugging
@ -213,7 +207,6 @@ class Login::SamlController < ApplicationController
case message
when SAML2::LogoutResponse
increment_saml_stat("logout_response_received")
if aac.debugging? && aac.debug_get(:logout_request_id) == message.in_response_to
aac.debug_set(:idp_logout_response_encoded, params[:SAMLResponse])
@ -266,7 +259,6 @@ class Login::SamlController < ApplicationController
return redirect_to saml_login_url(id: aac.id)
when SAML2::LogoutRequest
increment_saml_stat("logout_request_received")
if aac.debugging? && aac.debug_get(:logged_in_user_id) == @current_user.id
aac.debug_set(:idp_logout_request_encoded, params[:SAMLRequest])
@ -315,12 +307,11 @@ class Login::SamlController < ApplicationController
render xml: metadata.to_xml
end
def observee_validation
increment_saml_stat("login_attempt")
redirect_to delegated_auth_redirect_uri(
@domain_root_account.parent_registration_aac.generate_authn_request_redirect(host: request.host_with_port,
parent_registration: session[:parent_registration]))
@domain_root_account.parent_registration_aac.generate_authn_request_redirect(host: request.host_with_port,
parent_registration: session[:parent_registration])
)
end
protected
@ -338,10 +329,6 @@ class Login::SamlController < ApplicationController
end
end
def increment_saml_stat(key)
CanvasStatsd::Statsd.increment("saml.#{CanvasStatsd::Statsd.escape(request.host)}.#{key}")
end
def complete_observee_addition(registration_data)
observee_unique_id = registration_data[:observee][:unique_id]
observee = @domain_root_account.pseudonyms.by_unique_id(observee_unique_id).first.user

View File

@ -22,24 +22,20 @@ module Tracers
class DatadogTracer
def initialize(domain, first_party)
@domain = domain
@statsd = Datadog::Statsd.new('localhost', 8125)
@third_party = !first_party
end
def trace(key, metadata)
if key == "execute_query"
@statsd.batch do |statsd|
query_name = @third_party ?
"3rdparty" :
metadata[:query].operation_name || "unnamed"
tags = [
"domain:#@domain",
]
tags << "query_md5:#{Digest::MD5.hexdigest(metadata[:query].query_string)}" if !@third_party
statsd.increment("graphql.#{query_name}.count", tags: tags)
statsd.time("graphql.#{query_name}.time", tags: tags) do
yield
end
query_name = @third_party ? "3rdparty" : metadata[:query].operation_name || "unnamed"
tags = {
domain: @domain
}
tags[:query_md5] = Digest::MD5.hexdigest(metadata[:query].query_string).to_s unless @third_party
InstStatsd::Statsd.increment("graphql.#{query_name}.count", tags: tags)
InstStatsd::Statsd.time("graphql.#{query_name}.time", tags: tags) do
yield
end
else
yield

View File

@ -102,11 +102,11 @@ class RequestThrottle
return true
elsif blacklisted?(request)
Rails.logger.info("blocking request due to blacklist, client id: #{client_identifier(request)} ip: #{request.remote_ip}")
CanvasStatsd::Statsd.increment("request_throttling.blacklisted")
InstStatsd::Statsd.increment("request_throttling.blacklisted")
return false
else
if bucket.full?
CanvasStatsd::Statsd.increment("request_throttling.throttled")
InstStatsd::Statsd.increment("request_throttling.throttled")
if Setting.get("request_throttle.enabled", "true") == "true"
Rails.logger.info("blocking request due to throttling, client id: #{client_identifier(request)} bucket: #{bucket.to_json}")
return false
@ -189,9 +189,13 @@ class RequestThrottle
RequestContextGenerator.add_meta_header("y", "%.2f" % [system_cpu])
RequestContextGenerator.add_meta_header("d", "%.2f" % [db_runtime])
if account && account.shard.respond_to?(:database_server)
CanvasStatsd::Statsd.timing("requests_system_cpu.cluster_#{account.shard.database_server.id}", system_cpu)
CanvasStatsd::Statsd.timing("requests_user_cpu.cluster_#{account.shard.database_server.id}", user_cpu)
if account&.shard&.database_server
InstStatsd::Statsd.timing("requests_system_cpu.cluster_#{account.shard.database_server.id}", system_cpu,
short_stat: 'requests_system_cpu',
tags: {cluster: account.shard.database_server.id})
InstStatsd::Statsd.timing("requests_user_cpu.cluster_#{account.shard.database_server.id}", user_cpu,
short_stat: 'requests_user_cpu',
tags: {cluster: account.shard.database_server.id})
end
mem_stat = if starting_mem == 0 || ending_mem == 0

View File

@ -75,18 +75,18 @@ class Attachments::Verification
begin
body = Canvas::Security.decode_jwt(verifier)
if body[:id] != attachment.global_id
CanvasStatsd::Statsd.increment("attachments.token_verifier_id_mismatch")
InstStatsd::Statsd.increment("attachments.token_verifier_id_mismatch")
Rails.logger.warn("Attachment verifier token id mismatch. token id: #{body[:id]}, attachment id: #{attachment.global_id}, token: #{verifier}")
return nil
end
CanvasStatsd::Statsd.increment("attachments.token_verifier_success")
InstStatsd::Statsd.increment("attachments.token_verifier_success")
rescue Canvas::Security::TokenExpired
CanvasStatsd::Statsd.increment("attachments.token_verifier_expired")
InstStatsd::Statsd.increment("attachments.token_verifier_expired")
Rails.logger.warn("Attachment verifier token expired: #{verifier}")
return nil
rescue Canvas::Security::InvalidToken
CanvasStatsd::Statsd.increment("attachments.token_verifier_invalid")
InstStatsd::Statsd.increment("attachments.token_verifier_invalid")
Rails.logger.warn("Attachment verifier token invalid: #{verifier}")
return nil
end
@ -104,7 +104,7 @@ class Attachments::Verification
def valid_verifier_for_permission?(verifier, permission, session = {})
# Support for legacy verifiers.
if verifier == attachment.uuid
CanvasStatsd::Statsd.increment("attachments.legacy_verifier_success")
InstStatsd::Statsd.increment("attachments.legacy_verifier_success")
return true
end

View File

@ -187,6 +187,14 @@ class AuthenticationProvider::LDAP < AuthenticationProvider
::Canvas.timeout_protection_error_ttl("ldap:#{self.global_id}")
end
def ldap_account_ids_to_send_to_statsd
@ldap_account_ids_to_send_to_statsd ||= (InstStatsd.settings['ldap_account_ids_to_send_to_statsd'] || []).to_set
end
def should_send_to_statsd?
ldap_account_ids_to_send_to_statsd.include? Shard.global_id_for(account_id)
end
def ldap_bind_result(unique_id, password_plaintext)
return nil if password_plaintext.blank?
@ -199,16 +207,26 @@ class AuthenticationProvider::LDAP < AuthenticationProvider
ldap.bind_as(base: ldap.base, filter: filter, password: password_plaintext)
end
CanvasStatsd::Statsd.increment("#{statsd_prefix}.ldap_#{result ? 'success' : 'failure'}")
if should_send_to_statsd?
InstStatsd::Statsd.increment("#{statsd_prefix}.ldap_#{result ? 'success' : 'failure'}",
short_stat: "ldap_#{result ? 'success' : 'failure'}",
tags: {account_id: Shard.global_id_for(account_id), auth_provider_id: self.global_id})
end
result
rescue => e
::Canvas::Errors.capture(e, type: :ldap, account: self.account)
if e.is_a?(Timeout::Error)
CanvasStatsd::Statsd.increment("#{statsd_prefix}.ldap_timeout")
if should_send_to_statsd?
InstStatsd::Statsd.increment("#{statsd_prefix}.ldap_timeout",
short_stat: "ldap_timeout",
tags: {account_id: Shard.global_id_for(account_id), auth_provider_id: self.global_id})
end
self.update_attribute(:last_timeout_failure, Time.zone.now)
else
CanvasStatsd::Statsd.increment("#{statsd_prefix}.ldap_error")
elsif should_send_to_statsd?
InstStatsd::Statsd.increment("#{statsd_prefix}.ldap_error",
short_stat: "ldap_error",
tags: {account_id: Shard.global_id_for(account_id), auth_provider_id: self.global_id})
end
return nil
end

View File

@ -50,7 +50,7 @@ class BounceNotificationProcessor
if bounce_notification
process_bounce_notification(bounce_notification)
else
CanvasStatsd::Statsd.increment('bounce_notification_processor.processed.no_bounce')
InstStatsd::Statsd.increment('bounce_notification_processor.processed.no_bounce')
end
end
end
@ -71,13 +71,13 @@ class BounceNotificationProcessor
def process_bounce_notification(bounce_notification)
type = if is_suppression_bounce?(bounce_notification)
'suppression'
elsif is_permanent_bounce?(bounce_notification)
'permanent'
else
'transient'
end
CanvasStatsd::Statsd.increment("bounce_notification_processor.processed.#{type}")
'suppression'
elsif is_permanent_bounce?(bounce_notification)
'permanent'
else
'transient'
end
InstStatsd::Statsd.increment("bounce_notification_processor.processed.#{type}")
bouncy_addresses(bounce_notification).each do |address|
CommunicationChannel.bounce_for_path(

View File

@ -0,0 +1,25 @@
#
# Copyright (C) 2014 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas 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 Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
# Initialize canvas statsd configuration. See config/statsd.yml.example.
Rails.configuration.to_prepare do
settings = YAML.safe_load(Canvas::DynamicSettings.find(tree: :private)['statsd.yml'] || '')
settings ||= ConfigFile.load("statsd")
settings ||= {}
InstStatsd.settings = settings
end

View File

@ -18,7 +18,7 @@
Rails.configuration.to_prepare do
LiveEvents.logger = Rails.logger
LiveEvents.cache = Rails.cache
LiveEvents.statsd = CanvasStatsd::Statsd
LiveEvents.statsd = InstStatsd::Statsd
LiveEvents.max_queue_size = -> { Setting.get('live_events_max_queue_size', 1000).to_i }
LiveEvents.settings = -> {
plugin_settings = Canvas::Plugin.find(:live_events)&.settings

View File

@ -15,8 +15,8 @@
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
CanvasStatsd::DefaultTracking.track_sql
CanvasStatsd::DefaultTracking.track_active_record
CanvasStatsd::DefaultTracking.track_cache
CanvasStatsd::BlockTracking.logger = CanvasStatsd::RequestLogger.new(Rails.logger)
CanvasStatsd::RequestTracking.enable logger: Rails.logger
InstStatsd::DefaultTracking.track_sql
InstStatsd::DefaultTracking.track_active_record
InstStatsd::DefaultTracking.track_cache
InstStatsd::BlockTracking.logger = InstStatsd::RequestLogger.new(Rails.logger)
InstStatsd::RequestTracking.enable logger: Rails.logger

View File

@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'bookmarked_collection'
spec.add_dependency 'canvas_cassandra'
spec.add_dependency 'canvas_statsd'
spec.add_dependency 'inst_statsd'
spec.add_dependency 'json_token'
spec.add_dependency 'paginated_collection'

View File

@ -19,7 +19,7 @@ require 'active_support'
require 'active_record'
require 'bookmarked_collection'
require 'canvas_cassandra'
require 'canvas_statsd'
require 'inst_statsd'
module EventStream
require 'event_stream/attr_config'

View File

@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "mail", "~> 2.7.0"
spec.add_dependency "html_text_helper"
spec.add_dependency "utf8_cleaner"
spec.add_dependency "canvas_statsd"
spec.add_dependency "inst_statsd"
spec.add_dependency "aws-sdk-s3"
spec.add_dependency "aws-sdk-sqs"

View File

@ -18,7 +18,7 @@
require "html_text_helper"
require "mail"
require "utf8_cleaner"
require "canvas_statsd"
require "inst_statsd"
module IncomingMailProcessor
require "incoming_mail_processor/pop3_mailbox"

View File

@ -149,12 +149,15 @@ module IncomingMailProcessor
end
def report_stats(incoming_message, mailbox_account)
CanvasStatsd::Statsd.increment("incoming_mail_processor.incoming_message_processed.#{mailbox_account.escaped_address}")
InstStatsd::Statsd.increment("incoming_mail_processor.incoming_message_processed.#{mailbox_account.escaped_address}",
short_stat: 'incoming_mail_processor.incoming_message_processed',
tags: {mailbox: mailbox_account.escaped_address})
age = age(incoming_message)
if age
stat_name = "incoming_mail_processor.message_age.#{mailbox_account.escaped_address}"
CanvasStatsd::Statsd.timing(stat_name, age)
InstStatsd::Statsd.timing(stat_name, age,
short_stat: 'incoming_mail_processor.message_age',
tags: {mailbox: mailbox_account.escaped_address})
end
end

View File

@ -38,7 +38,9 @@ module IncomingMailProcessor
result.delete_if { |_k, v| v.nil? }
result.each_pair do |identifier, count|
name = "incoming_mail_processor.mailbox_queue_size.#{identifier}"
CanvasStatsd::Statsd.gauge name, count
InstStatsd::Statsd.gauge(name, count,
short_stat: 'incoming_mail_processor.mailbox_queue_size',
tags: {identifier: identifier})
end
end
private_class_method :report_unreads

View File

@ -37,7 +37,7 @@ module IncomingMailProcessor
end
def escaped_address
CanvasStatsd::Statsd.escape(address) unless address.nil?
InstStatsd::Statsd.escape(address) unless address.nil?
end
end
end

View File

@ -237,20 +237,23 @@ describe IncomingMailProcessor::IncomingMessageProcessor do
let (:message) { Mail.new(content_type: 'text/plain; charset=UTF-8', body: "hello") }
it "increments the processed count" do
expect(CanvasStatsd::Statsd).to receive(:increment).with("incoming_mail_processor.incoming_message_processed.").once
expect(InstStatsd::Statsd).to receive(:increment).with("incoming_mail_processor.incoming_message_processed.",
{short_stat: "incoming_mail_processor.incoming_message_processed", tags: {mailbox: nil}}).once
IncomingMessageProcessor.new(message_handler, error_reporter).process_single(message, '')
end
it "reports the age based on the date header" do
Timecop.freeze do
message.date = 10.minutes.ago
expect(CanvasStatsd::Statsd).to receive(:timing).once.with("incoming_mail_processor.message_age.", 10*60*1000)
expect(InstStatsd::Statsd).to receive(:timing).once.with("incoming_mail_processor.message_age.", 10*60*1000,
{short_stat: "incoming_mail_processor.message_age",
tags: {mailbox: nil}})
IncomingMessageProcessor.new(message_handler, error_reporter).process_single(message, '')
end
end
it "does not report the age if there is no date header" do
expect(CanvasStatsd::Statsd).to receive(:timing).never
expect(InstStatsd::Statsd).to receive(:timing).never
IncomingMessageProcessor.new(message_handler, error_reporter).process_single(message, '')
end
end

View File

@ -51,7 +51,9 @@ describe IncomingMailProcessor::Instrumentation do
it 'should push to statsd for one mailbox' do
IncomingMailProcessor::IncomingMessageProcessor.configure(single_config)
expect(CanvasStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.fake@fake_fake",4)
expect(InstStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.fake@fake_fake", 4,
{short_stat: "incoming_mail_processor.mailbox_queue_size",
tags: {identifier: "fake@fake_fake"}})
IncomingMailProcessor::Instrumentation.process
end
@ -59,9 +61,15 @@ describe IncomingMailProcessor::Instrumentation do
it 'should push to statsd for multiple mailboxes' do
IncomingMailProcessor::IncomingMessageProcessor.configure(multi_config)
expect(CanvasStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.user1@fake_fake", 4)
expect(CanvasStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.user3@fake_fake", 0)
expect(CanvasStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.user4@fake_fake", 50)
expect(InstStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.user1@fake_fake", 4,
{short_stat: "incoming_mail_processor.mailbox_queue_size",
tags: {identifier: "user1@fake_fake"}})
expect(InstStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.user3@fake_fake", 0,
{short_stat: "incoming_mail_processor.mailbox_queue_size",
tags: {identifier: "user3@fake_fake"}})
expect(InstStatsd::Statsd).to receive(:gauge).with("incoming_mail_processor.mailbox_queue_size.user4@fake_fake", 50,
{short_stat: "incoming_mail_processor.mailbox_queue_size",
tags: {identifier: "user4@fake_fake"}})
IncomingMailProcessor::Instrumentation.process
end

View File

@ -16,7 +16,7 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require 'canvas_statsd'
require 'inst_statsd'
module LiveEvents
class << self

View File

@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "aws-sdk-kinesis"
spec.add_dependency "canvas_statsd"
spec.add_dependency "inst_statsd"
spec.add_dependency "activesupport"
spec.add_development_dependency "bundler", "~> 1.5"

View File

@ -24,8 +24,8 @@ module Canvas
unless exception.is_a?(String) || exception.is_a?(Symbol)
category = exception.class.name
end
CanvasStatsd::Statsd.increment("errors.all")
CanvasStatsd::Statsd.increment("errors.#{category}")
InstStatsd::Statsd.increment("errors.all")
InstStatsd::Statsd.increment("errors.#{category}")
end
end
end

View File

@ -27,15 +27,15 @@ module Canvas
def self.error(type, identifier, operation, record, message)
logger.error "[#{type}:ERROR] #{identifier}:#{operation} #{record} [#{message}]"
CanvasStatsd::Statsd.increment("event_stream_failure.stream.#{CanvasStatsd::Statsd.escape(identifier)}")
InstStatsd::Statsd.increment("event_stream_failure.stream.#{InstStatsd::Statsd.escape(identifier)}")
if message.blank?
CanvasStatsd::Statsd.increment("event_stream_failure.exception.blank")
InstStatsd::Statsd.increment("event_stream_failure.exception.blank")
elsif message.include?("No live servers")
CanvasStatsd::Statsd.increment("event_stream_failure.exception.no_live_servers")
InstStatsd::Statsd.increment("event_stream_failure.exception.no_live_servers")
elsif message.include?("Unavailable")
CanvasStatsd::Statsd.increment("event_stream_failure.exception.unavailable")
InstStatsd::Statsd.increment("event_stream_failure.exception.unavailable")
else
CanvasStatsd::Statsd.increment("event_stream_failure.exception.other")
InstStatsd::Statsd.increment("event_stream_failure.exception.other")
end
end
end

View File

@ -83,8 +83,10 @@ module Canvas::Redis
raise
end
CanvasStatsd::Statsd.increment("redis.errors.all")
CanvasStatsd::Statsd.increment("redis.errors.#{CanvasStatsd::Statsd.escape(redis_name)}")
InstStatsd::Statsd.increment("redis.errors.all")
InstStatsd::Statsd.increment("redis.errors.#{InstStatsd::Statsd.escape(redis_name)}",
short_stat: 'redis.errors',
tags: {redis_name: InstStatsd::Statsd.escape(redis_name)})
Rails.logger.error "Failure handling redis command on #{redis_name}: #{e.inspect}"
Setting.skip_cache do

View File

@ -86,8 +86,14 @@ module Canvas::Twilio
end
# Ping StatsD about sending from this number
CanvasStatsd::Statsd.increment("notifications.twilio.message_sent_from_number.#{outbound_country}.#{outbound_number}")
CanvasStatsd::Statsd.increment("notifications.twilio.no_outbound_numbers_for.#{country}") unless country == outbound_country
InstStatsd::Statsd.increment("notifications.twilio.message_sent_from_number.#{outbound_country}.#{outbound_number}",
short_stat: 'notifications.twilio.message_sent',
tags: {country: outbound_country, number: outbound_number})
unless country == outbound_country
InstStatsd::Statsd.increment("notifications.twilio.no_outbound_numbers_for.#{country}",
short_stat: 'notifications.twilio.no_outbound_numbers',
tags: {country: country})
end
# Then send the message.
client.api.account.messages.create(from: outbound_number, to: recipient_number, body: body)

View File

@ -25,13 +25,12 @@ module Latex
attr_reader :latex
def parse
CanvasStatsd::Statsd.time("#{strategy}.parse_attempt") do
CanvasStatsd::Statsd.increment("#{strategy}.parse_attempt.count")
InstStatsd::Statsd.time("#{strategy}.parse_attempt") do
InstStatsd::Statsd.increment("#{strategy}.parse_attempt.count")
begin
send(:"#{strategy}_parse")
rescue Racc::ParseError, Ritex::LexError, Ritex::Error,
CanvasHttp::Error, Timeout::Error
CanvasStatsd::Statsd.increment("#{strategy}.parse_failure.count")
rescue Racc::ParseError, Ritex::LexError, Ritex::Error, CanvasHttp::Error, Timeout::Error
InstStatsd::Statsd.increment("#{strategy}.parse_failure.count")
return ""
end
end

View File

@ -61,7 +61,7 @@ describe GraphQLController do
context "data dog metrics" do
it "reports data dog metrics if requested" do
expect_any_instance_of(Datadog::Statsd).to receive(:increment).with("graphql.ASDF.count", any_args)
expect(InstStatsd::Statsd).to receive(:increment).with("graphql.ASDF.count", tags: anything)
request.headers["GraphQL-Metrics"] = "true"
post :execute, params: {query: 'query ASDF { course(id: "1") { id } }'}
end
@ -74,13 +74,13 @@ describe GraphQLController do
# this is the dumbest place to put this test except every where else i
# could think of
it "records datadog metrics if requested" do
expect_any_instance_of(Datadog::Statsd).to receive :increment
expect(InstStatsd::Statsd).to receive(:increment)
get :graphiql, params: {datadog_metric: "this_is_a_test"}
end
it "doesn't normally datadog" do
get :graphiql
expect_any_instance_of(Datadog::Statsd).not_to receive :increment
expect(InstStatsd::Statsd).not_to receive :increment
end
end
end

View File

@ -27,17 +27,28 @@ describe "memory and cpu tracking", type: :request do
user_cpu = 0
system_cpu = 0
if account.shard.respond_to?(:database_server)
expect(CanvasStatsd::Statsd).to receive(:timing).with("requests_user_cpu.cluster_#{account.shard.database_server.id}", user_cpu)
expect(CanvasStatsd::Statsd).to receive(:timing).with("requests_system_cpu.cluster_#{account.shard.database_server.id}", system_cpu)
expect(InstStatsd::Statsd).to receive(:timing).with("requests_user_cpu.cluster_#{account.shard.database_server.id}", user_cpu,
short_stat: 'requests_user_cpu',
tags: {cluster: account.shard.database_server.id})
expect(InstStatsd::Statsd).to receive(:timing).with("requests_system_cpu.cluster_#{account.shard.database_server.id}", system_cpu,
short_stat: 'requests_system_cpu',
tags: {cluster: account.shard.database_server.id})
end
expect(CanvasStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.total', kind_of(Numeric))
expect(InstStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.total',
kind_of(Numeric), {tags: {}, short_stat: '.total'})
# user_dashboard_view doesn't get populated here as there is no view_runtime to populate
expect(CanvasStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.db', kind_of(Numeric))
expect(CanvasStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.active_record', kind_of(Numeric))
expect(CanvasStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.sql.read', kind_of(Numeric))
expect(CanvasStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.sql.write', kind_of(Numeric))
expect(CanvasStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.sql.cache', kind_of(Numeric))
expect(CanvasStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.cache.read', kind_of(Numeric))
expect(InstStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.db',
kind_of(Numeric), {tags: {}, short_stat: '.db'})
expect(InstStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.active_record',
kind_of(Numeric), {tags: {}, short_stat: '.active_record'})
expect(InstStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.sql.read',
kind_of(Numeric), {tags: {}, short_stat: '.sql.read'})
expect(InstStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.sql.write',
kind_of(Numeric), {tags: {}, short_stat: '.sql.write'})
expect(InstStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.sql.cache',
kind_of(Numeric), {tags: {}, short_stat: '.sql.cache'})
expect(InstStatsd::Statsd).to receive(:timing).with('request.users.user_dashboard.cache.read',
kind_of(Numeric), {tags: {}, short_stat: '.cache.read'})
get "/"
end
end

View File

@ -22,27 +22,27 @@ module Canvas
describe ErrorStats do
describe ".capture" do
before(:each) do
allow(CanvasStatsd::Statsd).to receive(:increment)
allow(InstStatsd::Statsd).to receive(:increment)
end
let(:data){ {} }
it "increments errors.all always" do
expect(CanvasStatsd::Statsd).to receive(:increment).with("errors.all")
expect(InstStatsd::Statsd).to receive(:increment).with("errors.all")
described_class.capture("something", data)
end
it "increments the message name for a string" do
expect(CanvasStatsd::Statsd).to receive(:increment).with("errors.something")
expect(InstStatsd::Statsd).to receive(:increment).with("errors.something")
described_class.capture("something", data)
end
it "increments the message name for a symbol" do
expect(CanvasStatsd::Statsd).to receive(:increment).with("errors.something")
expect(InstStatsd::Statsd).to receive(:increment).with("errors.something")
described_class.capture(:something, data)
end
it "bumps the exception name for anything else" do
expect(CanvasStatsd::Statsd).to receive(:increment).with("errors.StandardError")
expect(InstStatsd::Statsd).to receive(:increment).with("errors.StandardError")
described_class.capture(StandardError.new, data)
end
end

View File

@ -71,7 +71,7 @@ describe "Canvas::Redis" do
end
it "should pass through other command errors" do
expect(CanvasStatsd::Statsd).to receive(:increment).never
expect(InstStatsd::Statsd).to receive(:increment).never
expect(Canvas.redis._client).to receive(:write).and_raise(Redis::CommandError.new("NOSCRIPT No matching script. Please use EVAL.")).once
expect { Canvas.redis.evalsha('xxx') }.to raise_error(Redis::CommandError)

View File

@ -135,9 +135,15 @@ describe 'Canvas::Twilio' do
stub_twilio(['+18015550100', '+18015550102'], '+18015550102' => 'CA', '+18015550103' => 'CA', '+18015550104' => 'GB')
expect(Canvas::Twilio.client.api.account.messages).to receive(:create).exactly(3).times
expect(CanvasStatsd::Statsd).to receive(:increment).with('notifications.twilio.message_sent_from_number.US.+18015550100').twice
expect(CanvasStatsd::Statsd).to receive(:increment).with('notifications.twilio.message_sent_from_number.CA.+18015550102')
expect(CanvasStatsd::Statsd).to receive(:increment).with('notifications.twilio.no_outbound_numbers_for.GB')
expect(InstStatsd::Statsd).to receive(:increment).with('notifications.twilio.message_sent_from_number.US.+18015550100',
short_stat: 'notifications.twilio.message_sent',
tags: {country: 'US', number: '+18015550100'}).twice
expect(InstStatsd::Statsd).to receive(:increment).with('notifications.twilio.message_sent_from_number.CA.+18015550102',
short_stat: 'notifications.twilio.message_sent',
tags: {country: 'CA', number: '+18015550102'})
expect(InstStatsd::Statsd).to receive(:increment).with('notifications.twilio.no_outbound_numbers_for.GB',
short_stat: 'notifications.twilio.no_outbound_numbers',
tags: {country: 'GB'})
Canvas::Twilio.deliver('+18015550101', 'message text')
Canvas::Twilio.deliver('+18015550103', 'message text')

View File

@ -70,21 +70,21 @@ describe Attachments::Verification do
context "verifying a verifier" do
it "should verify a legacy verifier for read and download" do
expect(CanvasStatsd::Statsd).to receive(:increment).with("attachments.legacy_verifier_success").twice
expect(InstStatsd::Statsd).to receive(:increment).with("attachments.legacy_verifier_success").twice
expect(v.valid_verifier_for_permission?(attachment.uuid, :read)).to eq(true)
expect(v.valid_verifier_for_permission?(attachment.uuid, :download)).to eq(true)
end
it "should return false on an expired verifier" do
expect(Canvas::Security).to receive(:decode_jwt).with("token").and_raise(Canvas::Security::TokenExpired)
expect(CanvasStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_expired")
expect(InstStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_expired")
expect(v.valid_verifier_for_permission?("token", :read)).to eq(false)
end
it "should return false on an invalid verifier" do
expect(Canvas::Security).to receive(:decode_jwt).with("token").and_raise(Canvas::Security::InvalidToken)
expect(CanvasStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_invalid")
expect(InstStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_invalid")
expect(v.valid_verifier_for_permission?("token", :read)).to eq(false)
end
@ -93,7 +93,7 @@ describe Attachments::Verification do
expect(Canvas::Security).to receive(:decode_jwt).with("token").and_return({
id: attachment.global_id + 1
})
expect(CanvasStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_id_mismatch")
expect(InstStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_id_mismatch")
expect(v.valid_verifier_for_permission?("token", :read)).to eq(false)
end
@ -105,7 +105,7 @@ describe Attachments::Verification do
expect(Canvas::Security).to receive(:decode_jwt).with("token").and_return({
id: att2.global_id, user_id: student.global_id
}).twice
expect(CanvasStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_success").twice
expect(InstStatsd::Statsd).to receive(:increment).with("attachments.token_verifier_success").twice
expect(v2.valid_verifier_for_permission?("token", :read)).to eq(true)
expect(v2.valid_verifier_for_permission?("token", :download)).to eq(false)

View File

@ -67,33 +67,44 @@ describe AuthenticationProvider::LDAP do
before do
@ldap = double()
allow(@ldap).to receive(:base)
expect(@aac).to receive(:ldap_connection).and_return(@ldap)
expect(@aac).to receive(:ldap_filter).and_return(nil)
allow(@aac).to receive(:ldap_connection).and_return(@ldap)
allow(@aac).to receive(:ldap_filter).and_return(nil)
allow(@aac).to receive(:account_id).and_return(1)
allow(@aac).to receive(:global_id).and_return(2)
allow(@aac).to receive(:should_send_to_statsd?).and_return(true)
end
it "should send to statsd on success" do
allow(@ldap).to receive(:bind_as).and_return(true)
expect(CanvasStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_success")
expect(InstStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_success",
short_stat: "ldap_success",
tags: {account_id: Shard.global_id_for(@aac.account_id), auth_provider_id: @aac.global_id})
@aac.ldap_bind_result('user', 'pass')
end
it "should send to statsd on failure" do
allow(@ldap).to receive(:bind_as).and_return(false)
expect(CanvasStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_failure")
expect(InstStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_failure",
short_stat: "ldap_failure",
tags: {account_id: Shard.global_id_for(@aac.account_id), auth_provider_id: @aac.global_id})
@aac.ldap_bind_result('user', 'pass')
end
it "should send to statsd on timeout" do
allow(@ldap).to receive(:bind_as).and_raise(Timeout::Error)
expect(CanvasStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_timeout")
allow(CanvasStatsd::Statsd).to receive(:increment).with(not_eq("#{@aac.send(:statsd_prefix)}.ldap_timeout"))
expect(InstStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_timeout",
short_stat: "ldap_timeout",
tags: {account_id: Shard.global_id_for(@aac.account_id), auth_provider_id: @aac.global_id})
allow(InstStatsd::Statsd).to receive(:increment).with(not_eq("#{@aac.send(:statsd_prefix)}.ldap_timeout"))
@aac.ldap_bind_result('user', 'pass')
end
it "should send to statsd on exception" do
allow(@ldap).to receive(:bind_as).and_raise(StandardError)
expect(CanvasStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_error")
allow(CanvasStatsd::Statsd).to receive(:increment).with(not_eq("#{@aac.send(:statsd_prefix)}.ldap_error"))
expect(InstStatsd::Statsd).to receive(:increment).with("#{@aac.send(:statsd_prefix)}.ldap_error",
short_stat: "ldap_error",
tags: {account_id: Shard.global_id_for(@aac.account_id), auth_provider_id: @aac.global_id})
allow(InstStatsd::Statsd).to receive(:increment).with(not_eq("#{@aac.send(:statsd_prefix)}.ldap_error"))
@aac.ldap_bind_result('user', 'pass')
end
end

View File

@ -104,10 +104,10 @@ describe BounceNotificationProcessor do
allow(bnp).to receive(:bounce_queue).and_return(queue)
allow(CommunicationChannel).to receive(:bounce_for_path)
expect(CanvasStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.transient').once
expect(CanvasStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.no_bounce').twice
expect(CanvasStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.suppression').exactly(3).times
expect(CanvasStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.permanent').exactly(4).times
expect(InstStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.transient').once
expect(InstStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.no_bounce').twice
expect(InstStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.suppression').exactly(3).times
expect(InstStatsd::Statsd).to receive(:increment).with('bounce_notification_processor.processed.permanent').exactly(4).times
bnp.process
end