Commit ffe85f88 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent d60270937fd5
<script>
import { mapActions, mapState } from 'vuex';
import { GlEmptyState, GlButton, GlLink, GlLoadingIcon, GlTable } from '@gitlab/ui';
import { mapActions, mapState, mapGetters } from 'vuex';
import {
GlEmptyState,
GlButton,
GlLink,
GlLoadingIcon,
GlTable,
GlSearchBoxByType,
} from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { __ } from '~/locale';
......@@ -20,6 +27,7 @@ export default {
GlLink,
GlLoadingIcon,
GlTable,
GlSearchBoxByType,
Icon,
TimeAgo,
},
......@@ -48,8 +56,17 @@ export default {
required: true,
},
},
data() {
return {
errorSearchQuery: '',
};
},
computed: {
...mapState(['errors', 'externalUrl', 'loading']),
...mapGetters(['filterErrorsByTitle']),
filteredErrors() {
return this.errorSearchQuery ? this.filterErrorsByTitle(this.errorSearchQuery) : this.errors;
},
},
created() {
if (this.errorTrackingEnabled) {
......@@ -71,10 +88,17 @@ export default {
<gl-loading-icon :size="3" />
</div>
<div v-else>
<div class="d-flex justify-content-end">
<div class="d-flex flex-row justify-content-around bg-secondary border">
<gl-search-box-by-type
v-model="errorSearchQuery"
class="col-lg-10 m-3 p-0"
:placeholder="__('Search or filter results...')"
type="search"
autofocus
/>
<gl-button
v-track-event="trackViewInSentryOptions(externalUrl)"
class="my-3 ml-auto"
class="m-3"
variant="primary"
:href="externalUrl"
target="_blank"
......@@ -84,7 +108,14 @@ export default {
</gl-button>
</div>
<gl-table :items="errors" :fields="$options.fields" :show-empty="true" fixed stacked="sm">
<gl-table
class="mt-3"
:items="filteredErrors"
:fields="$options.fields"
:show-empty="true"
fixed
stacked="sm"
>
<template slot="HEAD_events" slot-scope="data">
<div class="text-md-right">{{ data.label }}</div>
</template>
......
export const filterErrorsByTitle = state => errorQuery =>
state.errors.filter(error => error.title.match(new RegExp(`${errorQuery}`, 'i')));
export default () => {};
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
import * as getters from './getters';
import mutations from './mutations';
Vue.use(Vuex);
......@@ -14,6 +15,7 @@ export const createStore = () =>
},
actions,
mutations,
getters,
});
export default createStore();
......@@ -156,14 +156,21 @@ def charts
def test_report
return unless Feature.enabled?(:junit_pipeline_view, project)
if pipeline_test_report == :error
render json: { status: :error_parsing_report }
return
end
respond_to do |format|
format.html do
render 'show'
end
render json: TestReportSerializer
.new(current_user: @current_user)
.represent(pipeline_test_report)
format.json do
if pipeline_test_report == :error
render json: { status: :error_parsing_report }
else
render json: TestReportSerializer
.new(current_user: @current_user)
.represent(pipeline_test_report)
end
end
end
end
private
......
......@@ -19,7 +19,7 @@
= author_avatar(commit, size: 36, has_tooltip: false)
.commit-row-title
%span.item-title.str-truncated-100
= link_to_markdown commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
= link_to commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
.float-right
= link_to commit.short_id, project_commit_path(@project, commit), class: "commit-sha"
&nbsp;
......
---
title: Drop `id` column from `ci_build_trace_sections` table
merge_request: 18741
author:
type: changed
---
title: Do not render links in commit message on blame page
merge_request: 19128
author:
type: performance
---
title: Search list of Sentry errors by title in Gitlab
merge_request: 18772
author:
type: added
---
title: Fix Gitaly call duration measurements
merge_request: 18785
author:
type: fixed
# frozen_string_literal: true
class DropCiBuildTraceSectionsId < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
##
# This column has already been ignored since 12.4
# See https://gitlab.com/gitlab-org/gitlab/issues/32569
remove_column :ci_build_trace_sections, :id
end
def down
##
# We don't backfill serial ids as it's not used in application code
# and quite expensive process.
add_column :ci_build_trace_sections, :id, :bigint
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_10_17_094449) do
ActiveRecord::Schema.define(version: 2019_10_17_180026) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
......@@ -599,7 +599,7 @@
t.index ["project_id", "name"], name: "index_ci_build_trace_section_names_on_project_id_and_name", unique: true
end
create_table "ci_build_trace_sections", id: :serial, force: :cascade do |t|
create_table "ci_build_trace_sections", id: false, force: :cascade do |t|
t.integer "project_id", null: false
t.datetime "date_start", null: false
t.datetime "date_end", null: false
......
......@@ -41,5 +41,6 @@ NOTE: **Note:**
You will need at least Reporter [permissions](../../permissions.md) to view the Error Tracking list.
The Error Tracking list may be found at **Operations > Error Tracking** in your project's sidebar.
Errors can be filtered by title.
![Error Tracking list](img/error_tracking_list.png)
......@@ -142,18 +142,39 @@ def self.connection_data(storage)
# kwargs.merge(deadline: Time.now + 10)
# end
#
def self.call(storage, service, rpc, request, remote_storage: nil, timeout: default_timeout)
start = Gitlab::Metrics::System.monotonic_time
request_hash = request.is_a?(Google::Protobuf::MessageExts) ? request.to_h : {}
def self.call(storage, service, rpc, request, remote_storage: nil, timeout: default_timeout, &block)
self.measure_timings(service, rpc, request) do
self.execute(storage, service, rpc, request, remote_storage: remote_storage, timeout: timeout, &block)
end
end
# This method is like GitalyClient.call but should be used with
# Gitaly streaming RPCs. It measures how long the the RPC took to
# produce the full response, not just the initial response.
def self.streaming_call(storage, service, rpc, request, remote_storage: nil, timeout: default_timeout)
self.measure_timings(service, rpc, request) do
response = self.execute(storage, service, rpc, request, remote_storage: remote_storage, timeout: timeout)
yield(response)
end
end
def self.execute(storage, service, rpc, request, remote_storage:, timeout:)
enforce_gitaly_request_limits(:call)
kwargs = request_kwargs(storage, timeout: timeout.to_f, remote_storage: remote_storage)
kwargs = yield(kwargs) if block_given?
stub(service, storage).__send__(rpc, request, kwargs) # rubocop:disable GitlabSecurity/PublicSend
end
def self.measure_timings(service, rpc, request)
start = Gitlab::Metrics::System.monotonic_time
yield
ensure
duration = Gitlab::Metrics::System.monotonic_time - start
request_hash = request.is_a?(Google::Protobuf::MessageExts) ? request.to_h : {}
# Keep track, separately, for the performance bar
self.query_time += duration
......
......@@ -200,8 +200,9 @@ def between(from, to)
to: to
)
response = GitalyClient.call(@repository.storage, :commit_service, :commits_between, request, timeout: GitalyClient.medium_timeout)
consume_commits_response(response)
GitalyClient.streaming_call(@repository.storage, :commit_service, :commits_between, request, timeout: GitalyClient.medium_timeout) do |response|
consume_commits_response(response)
end
end
def diff_stats(left_commit_sha, right_commit_sha)
......@@ -224,8 +225,9 @@ def find_all_commits(opts = {})
)
request.order = opts[:order].upcase if opts[:order].present?
response = GitalyClient.call(@repository.storage, :commit_service, :find_all_commits, request, timeout: GitalyClient.medium_timeout)
consume_commits_response(response)
GitalyClient.streaming_call(@repository.storage, :commit_service, :find_all_commits, request, timeout: GitalyClient.medium_timeout) do |response|
consume_commits_response(response)
end
end
def list_commits_by_oid(oids)
......@@ -233,8 +235,9 @@ def list_commits_by_oid(oids)
request = Gitaly::ListCommitsByOidRequest.new(repository: @gitaly_repo, oid: oids)
response = GitalyClient.call(@repository.storage, :commit_service, :list_commits_by_oid, request, timeout: GitalyClient.medium_timeout)
consume_commits_response(response)
GitalyClient.streaming_call(@repository.storage, :commit_service, :list_commits_by_oid, request, timeout: GitalyClient.medium_timeout) do |response|
consume_commits_response(response)
end
rescue GRPC::NotFound # If no repository is found, happens mainly during testing
[]
end
......@@ -249,8 +252,9 @@ def commits_by_message(query, revision: '', path: '', limit: 1000, offset: 0)
offset: offset.to_i
)
response = GitalyClient.call(@repository.storage, :commit_service, :commits_by_message, request, timeout: GitalyClient.medium_timeout)
consume_commits_response(response)
GitalyClient.streaming_call(@repository.storage, :commit_service, :commits_by_message, request, timeout: GitalyClient.medium_timeout) do |response|
consume_commits_response(response)
end
end
def languages(ref = nil)
......@@ -323,9 +327,9 @@ def find_commits(options)
request.paths = encode_repeated(Array(options[:path])) if options[:path].present?
response = GitalyClient.call(@repository.storage, :commit_service, :find_commits, request, timeout: GitalyClient.medium_timeout)
consume_commits_response(response)
GitalyClient.streaming_call(@repository.storage, :commit_service, :find_commits, request, timeout: GitalyClient.medium_timeout) do |response|
consume_commits_response(response)
end
end
def filter_shas_with_signatures(shas)
......
import * as getters from '~/error_tracking/store/getters';
describe('Error Tracking getters', () => {
let state;
const mockErrors = [
{ title: 'ActiveModel::MissingAttributeError: missing attribute: encrypted_password' },
{ title: 'Grape::Exceptions::MethodNotAllowed: Grape::Exceptions::MethodNotAllowed' },
{ title: 'NoMethodError: undefined method `sanitize_http_headers=' },
{ title: 'NoMethodError: undefined method `pry' },
];
beforeEach(() => {
state = {
errors: mockErrors,
};
});
describe('search results', () => {
it('should return errors filtered by words in title matching the query', () => {
const filteredErrors = getters.filterErrorsByTitle(state)('NoMethod');
expect(filteredErrors).not.toContainEqual(mockErrors[0]);
expect(filteredErrors.length).toBe(2);
});
it('should not return results if there is no matching query', () => {
const filteredErrors = getters.filterErrorsByTitle(state)('GitLab');
expect(filteredErrors.length).toBe(0);
});
});
});
......@@ -377,6 +377,8 @@ def call_gitaly(count = 1)
context 'when the request store is active', :request_store do
it 'records call details if a RPC is called' do
expect(described_class).to receive(:measure_timings).and_call_original
gitaly_server.server_version
expect(described_class.list_call_details).not_to be_empty
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment