mn_utils_gem 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/mn_utils_gem/site_action.rb +144 -0
- data/lib/mn_utils_gem/version.rb +3 -0
- data/lib/mn_utils_gem.rb +6 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 419e0bfbbf1a78e1c98adcfbb2a9bfac214572f1cfd6c3f7f3b3a261e3e58e2d
|
4
|
+
data.tar.gz: bc949046b18e79169aeb93231177fbbcb518fb920d45391a90900e781c7695b6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f6d4f8e1121c6667735824ed70cdd2f5069dcadd8f7fa2cb01c75c6c008d1187a8a507c79c58a15e573e52891163975206ce226e2c9c15f6217f8f998d550086
|
7
|
+
data.tar.gz: d9e34a791f3d3c392d23d6ed3fe0f3da90f6413ba2d1da9ff26a898e6d8798629409f252e0384d3753a63f65e1e88fb49044f4fd59517b05dc75df57fd7c4223
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'gelf'
|
2
|
+
require 'aws-sdk-cloudwatch'
|
3
|
+
require 'request_store'
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
# SiteAction class to log important site actions to Graylog
|
7
|
+
# and send a matching metric to Cloudwatch
|
8
|
+
#
|
9
|
+
# usage: MnUtils::SiteAction.instance.log(message, site_action, optional_payload)
|
10
|
+
#
|
11
|
+
# eg: MnUtils::SiteAction.instance.log(
|
12
|
+
# "Login attempted with non-existent email",
|
13
|
+
# :login_attempt_nonexistent_email,
|
14
|
+
# {_email: "fish@banana.com", _request_ip: "123.123.123.123"}
|
15
|
+
# )
|
16
|
+
# This logs all the details in Graylog and records a count of 1
|
17
|
+
# against a Cloudwatch metric called login_attempt_nonexistent_email in namespace mn/auth
|
18
|
+
#
|
19
|
+
# The optional payload should be a simple flat hash with all keys starting
|
20
|
+
# with an underscore _ and all values being strings
|
21
|
+
|
22
|
+
module MnUtils
|
23
|
+
class SiteAction
|
24
|
+
|
25
|
+
include Singleton
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
# add new site actions here under the relevant group
|
29
|
+
# NO DUPLICATES please - a site action can only exist under one group
|
30
|
+
@_site_actions_and_groups = {
|
31
|
+
test: [
|
32
|
+
:test_event_1,
|
33
|
+
:test_event_2
|
34
|
+
],
|
35
|
+
reg: [
|
36
|
+
:reg_success_via_email,
|
37
|
+
:reg_success_via_google,
|
38
|
+
:reg_success_via_facebook,
|
39
|
+
:reg_attempt_invalid_email,
|
40
|
+
:reg_attempt_invalid_password,
|
41
|
+
:reg_attempt_invalid_username,
|
42
|
+
],
|
43
|
+
auth: [
|
44
|
+
:login_success_via_email,
|
45
|
+
:login_success_via_google,
|
46
|
+
:login_success_via_facebook,
|
47
|
+
:login_attempt_invalid_email,
|
48
|
+
:login_attempt_nonexistent_email,
|
49
|
+
:login_attempt_invalid_password,
|
50
|
+
:login_attempt_incorrect_password,
|
51
|
+
],
|
52
|
+
}.freeze
|
53
|
+
|
54
|
+
# this creates a reverse map of all site actions and their corresponding group
|
55
|
+
# for quick lookups by the code
|
56
|
+
@_site_action_group_map = Hash[*(@_site_actions_and_groups.map {|k,v| v.map {|x| [x, k]}}.flatten)].freeze
|
57
|
+
end
|
58
|
+
|
59
|
+
def log(message, site_action, payload = {})
|
60
|
+
|
61
|
+
# validate the parameters
|
62
|
+
raise ArgumentError, 'message cannot be blank' \
|
63
|
+
if message.blank?
|
64
|
+
raise ArgumentError, 'site_action must be a symbol' \
|
65
|
+
unless site_action.is_a?(Symbol)
|
66
|
+
raise ArgumentError, 'payload must be a hash' \
|
67
|
+
unless payload.is_a?(Hash)
|
68
|
+
raise ArgumentError, 'site_action value is not in allowed list' \
|
69
|
+
unless @_site_action_group_map.key? site_action
|
70
|
+
|
71
|
+
# validate the payload hash
|
72
|
+
payload.each do |key, value|
|
73
|
+
raise ArgumentError, "payload key #{key} must be a symbol" \
|
74
|
+
unless key.is_a?(Symbol)
|
75
|
+
key_string = key.to_s
|
76
|
+
raise ArgumentError, "payload key #{key} must begin with an underscore" \
|
77
|
+
unless key_string.chars.first == '_'
|
78
|
+
raise ArgumentError, "payload key #{key} must be at least 2 characters long" \
|
79
|
+
unless key_string.length >= 2
|
80
|
+
raise ArgumentError, "payload key cannot be _id" \
|
81
|
+
if key_string == '_id'
|
82
|
+
raise ArgumentError, "payload value for key #{key} must be a string" \
|
83
|
+
unless value.is_a?(String)
|
84
|
+
end
|
85
|
+
|
86
|
+
# validate the environment variables we need
|
87
|
+
raise ArgumentError, "ENV['SRV_CODE'] cannot be blank" \
|
88
|
+
unless ENV.key? 'SRV_CODE'
|
89
|
+
|
90
|
+
# setup the full payload
|
91
|
+
full_payload = payload.dup
|
92
|
+
full_payload[:short_message] = message
|
93
|
+
full_payload[:_site_action_group] = @_site_action_group_map[site_action]
|
94
|
+
full_payload[:_site_action] = site_action
|
95
|
+
full_payload[:_srv_code] = ENV['SRV_CODE']
|
96
|
+
|
97
|
+
# add the request ID if available
|
98
|
+
if RequestStore.store[:request_id]
|
99
|
+
full_payload[:_request_id] = RequestStore.store[:request_id]
|
100
|
+
end
|
101
|
+
|
102
|
+
# send it off
|
103
|
+
send_to_graylog full_payload
|
104
|
+
send_to_cloudwatch full_payload
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def send_to_graylog(payload)
|
111
|
+
if ENV.key?('GRAYLOG_GELF_UDP_HOST') && ENV.key?('GRAYLOG_GELF_UDP_PORT')
|
112
|
+
n = GELF::Notifier.new(ENV['GRAYLOG_GELF_UDP_HOST'], ENV['GRAYLOG_GELF_UDP_PORT'])
|
113
|
+
n.notify! payload
|
114
|
+
else
|
115
|
+
Rails.logger.debug("Payload for Graylog: #{payload}")
|
116
|
+
end
|
117
|
+
rescue Exception => e
|
118
|
+
Rails.logger.error e
|
119
|
+
end
|
120
|
+
|
121
|
+
def send_to_cloudwatch(payload)
|
122
|
+
metric_name = payload[:_site_action]
|
123
|
+
metric_data = [{
|
124
|
+
metric_name: metric_name,
|
125
|
+
value: 1,
|
126
|
+
unit: "Count"
|
127
|
+
}]
|
128
|
+
if ENV.key?'CLOUDWATCH_ROOT_NAMESPACE'
|
129
|
+
root_namespace = ENV['CLOUDWATCH_ROOT_NAMESPACE']
|
130
|
+
second_namespace = payload[:_site_action_group]
|
131
|
+
namespace = "#{root_namespace}/#{second_namespace}"
|
132
|
+
cw = Aws::CloudWatch::Client.new
|
133
|
+
cw.put_metric_data({
|
134
|
+
namespace: namespace,
|
135
|
+
metric_data: metric_data
|
136
|
+
})
|
137
|
+
else
|
138
|
+
Rails.logger.debug("Payload for Cloudwatch #{metric_data}")
|
139
|
+
end
|
140
|
+
rescue Exception => e
|
141
|
+
Rails.logger.error e
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
data/lib/mn_utils_gem.rb
ADDED
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mn_utils_gem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shamim Mirzai
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gelf
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aws-sdk-cloudwatch
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: request_store
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.17'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.17'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- lib/mn_utils_gem.rb
|
104
|
+
- lib/mn_utils_gem/site_action.rb
|
105
|
+
- lib/mn_utils_gem/version.rb
|
106
|
+
homepage: https://github.com/mumsnet/mn_utils_gem
|
107
|
+
licenses: []
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubygems_version: 3.0.3
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Mumsnet utils gem for microservices
|
128
|
+
test_files: []
|