diff --git a/qa/qa/support/loglinking.rb b/qa/qa/support/loglinking.rb index 5a1aad3c7eb55a10a58b587b3e94d9fbf60e344f..e9202af3965a20acc287dd96aee1f37a525414ae 100644 --- a/qa/qa/support/loglinking.rb +++ b/qa/qa/support/loglinking.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'active_support/core_ext/integer/time' - module QA module Support module Loglinking @@ -10,22 +8,6 @@ module Loglinking STAGING_REF_ADDRESS = 'https://staging-ref.gitlab.com' PRODUCTION_ADDRESS = 'https://gitlab.com' PRE_PROD_ADDRESS = 'https://pre.gitlab.com' - SENTRY_BASE_URLS = { - staging: 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg', - staging_ref: 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=all', - pre: 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=all', - production: 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd' - }.freeze - KIBANA_BASE_URLS = { - staging: 'https://nonprod-log.gitlab.net/', - production: 'https://log.gprd.gitlab.net/', - pre: 'https://nonprod-log.gitlab.net/' - }.freeze - KIBANA_INDICES = { - staging: 'ed942d00-5186-11ea-ad8a-f3610a492295', - production: '7092c4e2-4eb5-46f2-8305-a7da2edad090', - pre: 'pubsub-rails-inf-pre' - }.freeze class << self def failure_metadata(correlation_id) @@ -33,43 +15,23 @@ def failure_metadata(correlation_id) errors = ["Correlation Id: #{correlation_id}"] - env = get_logging_environment + env = logging_environment - unless env.nil? - sentry_base_url = get_sentry_base_url(env) - kibana_base_url = get_kibana_base_url(env) - kibana_index = get_kibana_index(env) + sentry = QA::Support::SystemLogs::Sentry.new(env, correlation_id) + sentry_url = sentry.url - errors << "Sentry Url: #{get_sentry_url(sentry_base_url, correlation_id)}" if sentry_base_url - errors << "Kibana Url: #{get_kibana_url(kibana_base_url, kibana_index, correlation_id)}" if kibana_base_url - end + kibana = QA::Support::SystemLogs::Kibana.new(env, correlation_id) + kibana_discover_url = kibana.discover_url + kibana_dashboard_url = kibana.dashboard_url - errors.join("\n") - end + errors << "Sentry Url: #{sentry_url}" if sentry_url + errors << "Kibana - Discover Url: #{kibana_discover_url}" if kibana_discover_url + errors << "Kibana - Dashboard Url: #{kibana_dashboard_url}" if kibana_dashboard_url - def get_sentry_base_url(env) - SENTRY_BASE_URLS[env] - end - - def get_sentry_url(base_url, correlation_id) - "#{base_url}&query=correlation_id%3A%22#{correlation_id}%22" - end - - def get_kibana_base_url(env) - KIBANA_BASE_URLS[env] - end - - def get_kibana_index(env) - KIBANA_INDICES[env] - end - - def get_kibana_url(base_url, index, correlation_id) - "#{base_url}app/discover#/?_a=%28index:%27#{index}%27%2Cquery%3A%28language%3Akuery%2C" \ - "query%3A%27json.correlation_id%20%3A%20#{correlation_id}%27%29%29" \ - "&_g=%28time%3A%28from%3A%27#{start_time}%27%2Cto%3A%27#{end_time}%27%29%29" + errors.join("\n") end - def get_logging_environment + def logging_environment address = QA::Runtime::Scenario.attributes[:gitlab_address] return if address.nil? @@ -86,14 +48,6 @@ def get_logging_environment nil end end - - def start_time - (Time.now.utc - 24.hours).iso8601(3) - end - - def end_time - Time.now.utc.iso8601(3) - end end end end diff --git a/qa/qa/support/system_logs/kibana.rb b/qa/qa/support/system_logs/kibana.rb new file mode 100644 index 0000000000000000000000000000000000000000..056323a6e3071866eb8ca10adad26196ffa70ca6 --- /dev/null +++ b/qa/qa/support/system_logs/kibana.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'active_support/core_ext/integer/time' + +module QA + module Support + module SystemLogs + class Kibana + BASE_URLS = { + staging: 'https://nonprod-log.gitlab.net/', + production: 'https://log.gprd.gitlab.net/', + pre: 'https://nonprod-log.gitlab.net/' + }.freeze + INDICES = { + staging: 'ed942d00-5186-11ea-ad8a-f3610a492295', + production: '7092c4e2-4eb5-46f2-8305-a7da2edad090', + pre: 'pubsub-rails-inf-pre' + }.freeze + DASHBOARD_IDS = { + staging: 'b74dc030-6f56-11ed-9af2-6131f0ee4ce6', + production: '5e6d3440-7597-11ed-9f43-e3784d7fe3ca', + pre: '15596340-7570-11ed-9af2-6131f0ee4ce6' + }.freeze + + def initialize(env, correlation_id) + @base_url = BASE_URLS[env] + @index = INDICES[env] + @dashboard_id = DASHBOARD_IDS[env] + @correlation_id = correlation_id + end + + def discover_url + return if @base_url.nil? + + "#{@base_url}app/discover#/?_a=%28index:%27#{@index}%27%2Cquery%3A%28language%3Akuery%2C" \ + "query%3A%27json.correlation_id%20%3A%20#{@correlation_id}%27%29%29" \ + "&_g=%28time%3A%28from%3A%27#{start_time}%27%2Cto%3A%27#{end_time}%27%29%29" + end + + def dashboard_url + return if @base_url.nil? + + "#{@base_url}app/dashboards#/view/#{@dashboard_id}?_g=%28time%3A%28from:%27#{start_time}%27%2C" \ + "to%3A%27#{end_time}%27%29%29&_a=%28filters%3A%21%28%28query%3A%28match_phrase%3A%28" \ + "json.correlation_id%3A%27#{@correlation_id}%27%29%29%29%29%29" + end + + private + + def start_time + (Time.now.utc - 24.hours).iso8601(3) + end + + def end_time + Time.now.utc.iso8601(3) + end + end + end + end +end diff --git a/qa/qa/support/system_logs/sentry.rb b/qa/qa/support/system_logs/sentry.rb new file mode 100644 index 0000000000000000000000000000000000000000..a1bd53e7d7a972faa6008c5f0a8ccb723b585671 --- /dev/null +++ b/qa/qa/support/system_logs/sentry.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module QA + module Support + module SystemLogs + class Sentry + BASE_URLS = { + staging: 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg', + staging_ref: 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=all', + pre: 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=all', + production: 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd' + }.freeze + + def initialize(env, correlation_id) + @base_url = BASE_URLS[env] + @correlation_id = correlation_id + end + + def url + return if @base_url.nil? + + "#{@base_url}&query=correlation_id%3A%22#{@correlation_id}%22" + end + end + end + end +end diff --git a/qa/spec/resource/api_fabricator_spec.rb b/qa/spec/resource/api_fabricator_spec.rb index 76cc8e0e3035b365002a67faa409a58d4abbba2b..0cec6b2a1eae8d15d6c59788e174d1faf7159069 100644 --- a/qa/spec/resource/api_fabricator_spec.rb +++ b/qa/spec/resource/api_fabricator_spec.rb @@ -125,7 +125,7 @@ def api_post_body it 'logs a correlation id' do response = double('Raw POST response', code: 400, body: post_response.to_json, headers: { x_request_id: 'foobar' }) - allow(QA::Support::Loglinking).to receive(:get_logging_environment).and_return(nil) + allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(nil) expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url)) expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(response) @@ -157,7 +157,8 @@ def api_post_body Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`. Correlation Id: foobar Sentry Url: https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg&query=correlation_id%3A%22foobar%22 - Kibana Url: https://nonprod-log.gitlab.net/app/discover#/?_a=%28index:%27ed942d00-5186-11ea-ad8a-f3610a492295%27%2Cquery%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20foobar%27%29%29&_g=%28time%3A%28from%3A%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29 + Kibana - Discover Url: https://nonprod-log.gitlab.net/app/discover#/?_a=%28index:%27ed942d00-5186-11ea-ad8a-f3610a492295%27%2Cquery%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20foobar%27%29%29&_g=%28time%3A%28from%3A%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29 + Kibana - Dashboard Url: https://nonprod-log.gitlab.net/app/dashboards#/view/b74dc030-6f56-11ed-9af2-6131f0ee4ce6?_g=%28time%3A%28from:%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29&_a=%28filters%3A%21%28%28query%3A%28match_phrase%3A%28json.correlation_id%3A%27foobar%27%29%29%29%29%29 ERROR end end diff --git a/qa/spec/support/loglinking_spec.rb b/qa/spec/support/loglinking_spec.rb index 3955d266ef622a302fa90acc6058b9f9019a3dbd..79004630253861c23b0e404782547a4429060548 100644 --- a/qa/spec/support/loglinking_spec.rb +++ b/qa/spec/support/loglinking_spec.rb @@ -13,103 +13,76 @@ end context 'when correlation_id exists' do - context 'and logging environment exists' do - it 'returns Sentry URL' do - allow(QA::Support::Loglinking).to receive(:get_logging_environment).and_return(:foo) - allow(QA::Support::Loglinking).to receive(:get_sentry_base_url).and_return('https://sentry.address/?environment=bar') - allow(QA::Support::Loglinking).to receive(:get_kibana_base_url).and_return(nil) - allow(QA::Support::Loglinking).to receive(:get_kibana_index).and_return(nil) + let(:correlation_id) { 'foo123' } + let(:sentry_url) { "https://sentry.address/?environment=bar&query=correlation_id%3A%22#{correlation_id}%22" } + let(:discover_url) { "https://kibana.address/app/discover#/?_a=%28index:%27pubsub-rails-inf-foo%27%2Cquery%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20#{correlation_id}%27%29%29&_g=%28time%3A%28from%3A%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29" } + let(:dashboard_url) { "https://kibana.address/app/dashboards#/view/abc-123-dashboard-id?_g=%28time%3A%28from:%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29&_a=%28filters%3A%21%28%28query%3A%28match_phrase%3A%28json.correlation_id%3A%27#{correlation_id}%27%29%29%29%29%29" } + + before do + allow(QA::Support::SystemLogs::Sentry).to receive(:new).and_return(sentry) + allow(QA::Support::SystemLogs::Kibana).to receive(:new).and_return(kibana) + end - expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql(<<~ERROR.chomp) - Correlation Id: foo123 - Sentry Url: https://sentry.address/?environment=bar&query=correlation_id%3A%22foo123%22 - ERROR + context 'and both Sentry and Kibana exist for the logging environment' do + let(:sentry) { instance_double(QA::Support::SystemLogs::Sentry, url: sentry_url) } + let(:kibana) do + instance_double(QA::Support::SystemLogs::Kibana, + discover_url: discover_url, dashboard_url: dashboard_url) end - it 'returns Kibana URL' do - time = Time.new(2022, 11, 14, 0, 0, 0, '+00:00') - - allow(QA::Support::Loglinking).to receive(:get_logging_environment).and_return(:foo) - allow(QA::Support::Loglinking).to receive(:get_sentry_base_url).and_return(nil) - allow(QA::Support::Loglinking).to receive(:get_kibana_base_url).and_return('https://kibana.address/') - allow(QA::Support::Loglinking).to receive(:get_kibana_index).and_return('pubsub-rails-inf-foo') - allow(Time).to receive(:now).and_return(time) - - expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql(<<~ERROR.chomp) + it 'returns both Sentry and Kibana URLs' do + expect(QA::Support::Loglinking.failure_metadata(correlation_id)).to eql(<<~ERROR.chomp) Correlation Id: foo123 - Kibana Url: https://kibana.address/app/discover#/?_a=%28index:%27pubsub-rails-inf-foo%27%2Cquery%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20foo123%27%29%29&_g=%28time%3A%28from%3A%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29 + Sentry Url: #{sentry_url} + Kibana - Discover Url: #{discover_url} + Kibana - Dashboard Url: #{dashboard_url} ERROR end end - context 'and logging environment does not exist' do - it 'returns only the correlation ID' do - allow(QA::Support::Loglinking).to receive(:get_logging_environment).and_return(nil) - - expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql('Correlation Id: foo123') + context 'and only Sentry exists for the logging environment' do + let(:sentry) { instance_double(QA::Support::SystemLogs::Sentry, url: sentry_url) } + let(:kibana) do + instance_double(QA::Support::SystemLogs::Kibana, + discover_url: nil, dashboard_url: nil) end - end - end - end - describe '.get_sentry_base_url' do - let(:url_hash) do - { - :staging => 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg', - :staging_ref => 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=all', - :pre => 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=all', - :production => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd', - :foo => nil, - nil => nil - } - end - - it 'returns Sentry base URL based on environment' do - url_hash.each do |environment, url| - expect(QA::Support::Loglinking.get_sentry_base_url(environment)).to eq(url) + it 'returns only Sentry URL' do + expect(QA::Support::Loglinking.failure_metadata(correlation_id)).to eql(<<~ERROR.chomp) + Correlation Id: foo123 + Sentry Url: #{sentry_url} + ERROR + end end - end - end - describe '.get_kibana_base_url' do - let(:url_hash) do - { - :staging => 'https://nonprod-log.gitlab.net/', - :staging_ref => nil, - :production => 'https://log.gprd.gitlab.net/', - :pre => 'https://nonprod-log.gitlab.net/', - :foo => nil, - nil => nil - } - end + context 'and only Kibana exists for the logging environment' do + let(:sentry) { instance_double(QA::Support::SystemLogs::Sentry, url: nil) } + let(:kibana) do + instance_double(QA::Support::SystemLogs::Kibana, + discover_url: discover_url, dashboard_url: dashboard_url) + end - it 'returns Kibana URL based on environment' do - url_hash.each do |environment, url| - expect(QA::Support::Loglinking.get_kibana_base_url(environment)).to eq(url) + it 'returns only Kibana Discover and Dashboard URLs' do + expect(QA::Support::Loglinking.failure_metadata(correlation_id)).to eql(<<~ERROR.chomp) + Correlation Id: foo123 + Kibana - Discover Url: #{discover_url} + Kibana - Dashboard Url: #{dashboard_url} + ERROR + end end - end - end - describe '.get_kibana_index' do - let(:index_hash) do - { - :staging => 'ed942d00-5186-11ea-ad8a-f3610a492295', - :staging_ref => nil, - :production => '7092c4e2-4eb5-46f2-8305-a7da2edad090', - :pre => 'pubsub-rails-inf-pre', - :foo => nil, - nil => nil - } - end + context 'and neither Sentry nor Kibana exists for the logging environment' do + let(:sentry) { instance_double(QA::Support::SystemLogs::Sentry, url: nil) } + let(:kibana) { instance_double(QA::Support::SystemLogs::Kibana, discover_url: nil, dashboard_url: nil) } - it 'returns Kibana index based on environment' do - index_hash.each do |environment, index| - expect(QA::Support::Loglinking.get_kibana_index(environment)).to eq(index) + it 'returns only the correlation ID' do + expect(QA::Support::Loglinking.failure_metadata(correlation_id)).to eql("Correlation Id: #{correlation_id}") + end end end end - describe '.get_logging_environment' do + describe '.logging_environment' do let(:staging_address) { 'https://staging.gitlab.com' } let(:staging_ref_address) { 'https://staging-ref.gitlab.com' } let(:production_address) { 'https://gitlab.com' } @@ -143,7 +116,7 @@ logging_env_array.each do |logging_env_hash| allow(QA::Runtime::Scenario).to receive(:attributes).and_return({ gitlab_address: logging_env_hash[:address] }) - expect(QA::Support::Loglinking.get_logging_environment).to eq(logging_env_hash[:expected_env]) + expect(QA::Support::Loglinking.logging_environment).to eq(logging_env_hash[:expected_env]) end end end diff --git a/qa/spec/support/system_logs/kibana_spec.rb b/qa/spec/support/system_logs/kibana_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..7e13f5a0a067b7aec4ab24e37bd80e89289029cf --- /dev/null +++ b/qa/spec/support/system_logs/kibana_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +RSpec.describe QA::Support::SystemLogs::Kibana do + using RSpec::Parameterized::TableSyntax + + let(:correlation_id) { 'foo123' } + + shared_examples 'returns the expected URL' do + where(:env, :expected_url) do + :staging | ref(:staging_url) + :production | ref(:production_url) + :pre | ref(:pre_url) + :foo | nil + nil | nil + end + + with_them do + before do + allow(Time).to receive(:now).and_return(Time.new(2022, 11, 14, 0, 0, 0, '+00:00')) + end + + specify do + expect(subject).to eq(expected_url) + end + end + end + + describe '#discover_url' do + subject { described_class.new(env, correlation_id).discover_url } + + let(:staging_url) do + "https://nonprod-log.gitlab.net/app/discover#/?_a=%28index:%27ed942d00-5186-11ea-ad8a-f3610a492295%27" \ + "%2Cquery%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20#{correlation_id}%27%29" \ + "%29&_g=%28time%3A%28from%3A%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29" + end + + let(:production_url) do + "https://log.gprd.gitlab.net/app/discover#/?_a=%28index:%277092c4e2-4eb5-46f2-8305-a7da2edad090%27" \ + "%2Cquery%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20#{correlation_id}%27%29" \ + "%29&_g=%28time%3A%28from%3A%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29" + end + + let(:pre_url) do + "https://nonprod-log.gitlab.net/app/discover#/?_a=%28index:%27pubsub-rails-inf-pre%27" \ + "%2Cquery%3A%28language%3Akuery%2Cquery%3A%27json.correlation_id%20%3A%20#{correlation_id}%27%29" \ + "%29&_g=%28time%3A%28from%3A%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29" + end + + it_behaves_like 'returns the expected URL' + end + + describe '#dashboard_url' do + subject { described_class.new(env, correlation_id).dashboard_url } + + let(:staging_url) do + "https://nonprod-log.gitlab.net/app/dashboards#/view/b74dc030-6f56-11ed-9af2-6131f0ee4ce6?_g=%28time" \ + "%3A%28from:%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29&_a=%28filters%3A%21" \ + "%28%28query%3A%28match_phrase%3A%28json.correlation_id%3A%27#{correlation_id}%27%29%29%29%29%29" + end + + let(:production_url) do + "https://log.gprd.gitlab.net/app/dashboards#/view/5e6d3440-7597-11ed-9f43-e3784d7fe3ca?_g=%28time" \ + "%3A%28from:%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29&_a=%28filters%3A%21" \ + "%28%28query%3A%28match_phrase%3A%28json.correlation_id%3A%27#{correlation_id}%27%29%29%29%29%29" + end + + let(:pre_url) do + "https://nonprod-log.gitlab.net/app/dashboards#/view/15596340-7570-11ed-9af2-6131f0ee4ce6?_g=%28time" \ + "%3A%28from:%272022-11-13T00:00:00.000Z%27%2Cto%3A%272022-11-14T00:00:00.000Z%27%29%29&_a=%28filters%3A%21" \ + "%28%28query%3A%28match_phrase%3A%28json.correlation_id%3A%27#{correlation_id}%27%29%29%29%29%29" + end + + it_behaves_like 'returns the expected URL' + end +end diff --git a/qa/spec/support/system_logs/sentry_spec.rb b/qa/spec/support/system_logs/sentry_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..6821c527b236cf2c1aace2aec0e2bb2df5f9b1a6 --- /dev/null +++ b/qa/spec/support/system_logs/sentry_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +RSpec.describe QA::Support::SystemLogs::Sentry do + using RSpec::Parameterized::TableSyntax + + let(:correlation_id) { 'foo123' } + + describe '#url' do + subject { described_class.new(env, correlation_id).url } + + let(:staging_url) do + "https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg&query=correlation_id%3A%22#{correlation_id}%22" + end + + let(:staging_ref_url) do + "https://sentry.gitlab.net/gitlab/staging-ref/?environment=all&query=correlation_id%3A%22#{correlation_id}%22" + end + + let(:pre_url) do + "https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=all&query=correlation_id%3A%22#{correlation_id}%22" + end + + let(:production_url) do + "https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd&query=correlation_id%3A%22#{correlation_id}%22" + end + + where(:env, :expected_url) do + :staging | ref(:staging_url) + :staging_ref | ref(:staging_ref_url) + :production | ref(:production_url) + :pre | ref(:pre_url) + :foo | nil + nil | nil + end + + with_them do + it 'returns the expected URL' do + expect(subject).to eq(expected_url) + end + end + end +end