Commit 11c57abb authored by Eugenia Grieff's avatar Eugenia Grieff

Merge branch 'master' into...

Merge branch 'master' into security-373-public-group-owners-maintainers-can-not-delete-comments-posted-on-epics
parents dc40b29b 140b20fd
......@@ -354,7 +354,7 @@ group :development, :test do
gem 'database_cleaner', '~> 1.7.0'
gem 'factory_bot_rails', '~> 4.8.2'
gem 'rspec-rails', '~> 3.7.0'
gem 'rspec-rails', '~> 3.8.0'
gem 'rspec-retry', '~> 0.6.1'
gem 'rspec_profiling', '~> 0.0.5'
gem 'rspec-set', '~> 0.1.3'
......
......@@ -814,36 +814,36 @@ GEM
chunky_png
rqrcode-rails3 (0.1.7)
rqrcode (>= 0.4.2)
rspec (3.7.0)
rspec-core (~> 3.7.0)
rspec-expectations (~> 3.7.0)
rspec-mocks (~> 3.7.0)
rspec-core (3.7.1)
rspec-support (~> 3.7.0)
rspec-expectations (3.7.0)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-core (3.8.2)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.4)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0)
rspec-mocks (3.7.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0)
rspec-support (~> 3.8.0)
rspec-parameterized (0.4.2)
binding_ninja (>= 0.2.3)
parser
proc_to_ast
rspec (>= 2.13, < 4)
unparser
rspec-rails (3.7.2)
rspec-rails (3.8.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.7.0)
rspec-expectations (~> 3.7.0)
rspec-mocks (~> 3.7.0)
rspec-support (~> 3.7.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-support (~> 3.8.0)
rspec-retry (0.6.1)
rspec-core (> 3.3)
rspec-set (0.1.3)
rspec-support (3.7.1)
rspec-support (3.8.2)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
rspec_profiling (0.0.5)
......@@ -1254,7 +1254,7 @@ DEPENDENCIES
rouge (~> 3.5)
rqrcode-rails3 (~> 0.1.7)
rspec-parameterized
rspec-rails (~> 3.7.0)
rspec-rails (~> 3.8.0)
rspec-retry (~> 0.6.1)
rspec-set (~> 0.1.3)
rspec_junit_formatter
......
......@@ -105,7 +105,7 @@ export default {
</script>
<template>
<div class="form-group">
<div class="confidential-merge-request-fork-group form-group">
<label>{{ __('Project') }}</label>
<div>
<dropdown
......@@ -126,6 +126,14 @@ export default {
{{ __('No forks available to you.') }}<br />
<span v-html="noForkText"></span>
</template>
<gl-link
:href="helpPagePath"
class="w-auto p-0 d-inline-block text-primary bg-transparent"
target="_blank"
>
<span class="sr-only">{{ __('Read more') }}</span>
<i class="fa fa-question-circle" aria-hidden="true"></i>
</gl-link>
</p>
</div>
</div>
......
......@@ -17,11 +17,13 @@ export default class FilterableList {
}
getFilterEndpoint() {
return `${this.filterForm.getAttribute('action')}?${$(this.filterForm).serialize()}`;
return this.getPagePath();
}
getPagePath() {
return this.getFilterEndpoint();
const action = this.filterForm.getAttribute('action');
const params = $(this.filterForm).serialize();
return `${action}${action.indexOf('?') > 0 ? '&' : '?'}${params}`;
}
initSearch() {
......
......@@ -8,6 +8,7 @@ import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import Icon from '~/vue_shared/components/icon.vue';
import { chartHeight, graphTypes, lineTypes } from '../../constants';
import { makeDataSeries } from '~/helpers/monitor_helper';
import { graphDataValidatorForValues } from '../../utils';
let debouncedResize;
......@@ -23,19 +24,7 @@ export default {
graphData: {
type: Object,
required: true,
validator(data) {
return (
Array.isArray(data.queries) &&
data.queries.filter(query => {
if (Array.isArray(query.result)) {
return (
query.result.filter(res => Array.isArray(res.values)).length === query.result.length
);
}
return false;
}).length === data.queries.length
);
},
validator: graphDataValidatorForValues.bind(null, false),
},
containerWidth: {
type: Number,
......
......@@ -4,6 +4,7 @@ import { debounceByAnimationFrame } from '~/lib/utils/common_utils';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import { chartHeight } from '../../constants';
import { makeDataSeries } from '~/helpers/monitor_helper';
import { graphDataValidatorForValues } from '../../utils';
export default {
components: {
......@@ -14,23 +15,11 @@ export default {
graphData: {
type: Object,
required: true,
validator(data) {
return (
Array.isArray(data.queries) &&
data.queries.filter(query => {
if (Array.isArray(query.result)) {
return (
query.result.filter(res => Array.isArray(res.values)).length === query.result.length
);
}
return false;
}).length === data.queries.length
);
},
containerWidth: {
type: Number,
required: true,
},
validator: graphDataValidatorForValues.bind(null, false),
},
containerWidth: {
type: Number,
required: true,
},
},
data() {
......
<script>
import { GlSingleStat } from '@gitlab/ui/dist/charts';
import { roundOffFloat } from '~/lib/utils/common_utils';
import { graphDataValidatorForValues } from '../../utils';
export default {
components: {
......@@ -7,22 +9,21 @@ export default {
},
inheritAttrs: false,
props: {
title: {
type: String,
required: true,
},
value: {
type: Number,
required: true,
},
unit: {
type: String,
graphData: {
type: Object,
required: true,
validator: graphDataValidatorForValues.bind(null, true),
},
},
computed: {
valueWithUnit() {
return `${this.value}${this.unit}`;
queryInfo() {
return this.graphData.queries[0];
},
engineeringNotation() {
return `${roundOffFloat(this.queryInfo.result[0].value[1], 1)}${this.queryInfo.unit}`;
},
graphTitle() {
return this.queryInfo.label;
},
},
};
......@@ -30,8 +31,8 @@ export default {
<template>
<div class="prometheus-graph col-12 col-lg-6">
<div class="prometheus-graph-header">
<h5 ref="graphTitle" class="prometheus-graph-title">{{ title }}</h5>
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
</div>
<gl-single-stat :value="valueWithUnit" :title="title" variant="success" />
<gl-single-stat :value="engineeringNotation" :title="graphTitle" variant="success" />
</div>
</template>
......@@ -7,6 +7,8 @@ import Icon from '~/vue_shared/components/icon.vue';
import { getParameterValues } from '~/lib/utils/url_utility';
import invalidUrl from '~/lib/utils/invalid_url';
import MonitorAreaChart from './charts/area.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
import PanelType from './panel_type.vue';
import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue';
import { timeWindows, timeWindowsKeyNames } from '../constants';
......@@ -18,6 +20,8 @@ let sidebarMutationObserver;
export default {
components: {
MonitorAreaChart,
MonitorSingleStatChart,
PanelType,
GraphGroup,
EmptyState,
Icon,
......@@ -152,6 +156,7 @@ export default {
'useDashboardEndpoint',
'allDashboards',
'multipleDashboardsEnabled',
'additionalPanelTypesEnabled',
]),
groupsWithData() {
return this.groups.filter(group => this.chartsWithData(group.metrics).length > 0);
......@@ -173,6 +178,7 @@ export default {
deploymentsEndpoint: this.deploymentsEndpoint,
dashboardEndpoint: this.dashboardEndpoint,
currentDashboard: this.currentDashboard,
projectPath: this.projectPath,
});
this.timeWindows = timeWindows;
......@@ -220,6 +226,8 @@ export default {
chart.metrics.some(metric => this.metricsWithData.includes(metric.metric_id)),
);
},
// TODO: BEGIN, Duplicated code with panel_type until feature flag is removed
// Issue number: https://gitlab.com/gitlab-org/gitlab-ce/issues/63845
getGraphAlerts(queries) {
if (!this.allAlerts) return {};
const metricIdsForChart = queries.map(q => q.metricId);
......@@ -228,6 +236,7 @@ export default {
getGraphAlertValues(queries) {
return Object.values(this.getGraphAlerts(queries));
},
// TODO: END
hideAddMetricModal() {
this.$refs.addMetricModal.hide();
},
......@@ -366,24 +375,34 @@ export default {
:name="groupData.group"
:show-panels="showPanels"
>
<monitor-area-chart
v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
:key="graphIndex"
:project-path="projectPath"
:graph-data="graphData"
:deployment-data="deploymentData"
:thresholds="getGraphAlertValues(graphData.queries)"
:container-width="elWidth"
group-id="monitor-area-chart"
>
<alert-widget
v-if="alertWidgetAvailable && graphData"
:alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.queries"
:alerts-to-manage="getGraphAlerts(graphData.queries)"
@setAlerts="setAlerts"
<template v-if="additionalPanelTypesEnabled">
<panel-type
v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
:key="`panel-type-${graphIndex}`"
:graph-data="graphData"
:dashboard-width="elWidth"
/>
</monitor-area-chart>
</template>
<template v-else>
<monitor-area-chart
v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
:key="graphIndex"
:graph-data="graphData"
:deployment-data="deploymentData"
:thresholds="getGraphAlertValues(graphData.queries)"
:container-width="elWidth"
:project-path="projectPath"
group-id="monitor-area-chart"
>
<alert-widget
v-if="alertWidgetAvailable && graphData"
:alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.queries"
:alerts-to-manage="getGraphAlerts(graphData.queries)"
@setAlerts="setAlerts"
/>
</monitor-area-chart>
</template>
</graph-group>
</div>
<empty-state
......
<script>
import { mapState } from 'vuex';
import _ from 'underscore';
import MonitorAreaChart from './charts/area.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
export default {
components: {
MonitorAreaChart,
MonitorSingleStatChart,
},
props: {
graphData: {
type: Object,
required: true,
},
dashboardWidth: {
type: Number,
required: true,
},
},
computed: {
...mapState('monitoringDashboard', ['deploymentData', 'projectPath']),
alertWidgetAvailable() {
return IS_EE && this.prometheusAlertsAvailable && this.alertsEndpoint && this.graphData;
},
},
methods: {
getGraphAlerts(queries) {
if (!this.allAlerts) return {};
const metricIdsForChart = queries.map(q => q.metricId);
return _.pick(this.allAlerts, alert => metricIdsForChart.includes(alert.metricId));
},
getGraphAlertValues(queries) {
return Object.values(this.getGraphAlerts(queries));
},
isPanelType(type) {
return this.graphData.type && this.graphData.type === type;
},
},
};
</script>
<template>
<monitor-single-stat-chart v-if="isPanelType('single-stat')" :graph-data="graphData" />
<monitor-area-chart
v-else
:graph-data="graphData"
:deployment-data="deploymentData"
:project-path="projectPath"
:thresholds="getGraphAlertValues(graphData.queries)"
:container-width="dashboardWidth"
group-id="monitor-area-chart"
>
<alert-widget
v-if="alertWidgetAvailable"
:alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.queries"
:alerts-to-manage="getGraphAlerts(graphData.queries)"
@setAlerts="setAlerts"
/>
</monitor-area-chart>
</template>
......@@ -12,6 +12,7 @@ export default (props = {}) => {
store.dispatch('monitoringDashboard/setFeatureFlags', {
prometheusEndpointEnabled: gon.features.environmentMetricsUsePrometheusEndpoint,
multipleDashboardsEnabled: gon.features.environmentMetricsShowMultipleDashboards,
additionalPanelTypesEnabled: gon.features.environmentMetricsAdditionalPanelTypes,
});
}
......
......@@ -37,10 +37,11 @@ export const setEndpoints = ({ commit }, endpoints) => {
export const setFeatureFlags = (
{ commit },
{ prometheusEndpointEnabled, multipleDashboardsEnabled },
{ prometheusEndpointEnabled, multipleDashboardsEnabled, additionalPanelTypesEnabled },
) => {
commit(types.SET_DASHBOARD_ENABLED, prometheusEndpointEnabled);
commit(types.SET_MULTIPLE_DASHBOARDS_ENABLED, multipleDashboardsEnabled);
commit(types.SET_ADDITIONAL_PANEL_TYPES_ENABLED, additionalPanelTypesEnabled);
};
export const requestMetricsDashboard = ({ commit }) => {
......
......@@ -11,6 +11,7 @@ export const SET_QUERY_RESULT = 'SET_QUERY_RESULT';
export const SET_TIME_WINDOW = 'SET_TIME_WINDOW';
export const SET_DASHBOARD_ENABLED = 'SET_DASHBOARD_ENABLED';
export const SET_MULTIPLE_DASHBOARDS_ENABLED = 'SET_MULTIPLE_DASHBOARDS_ENABLED';
export const SET_ADDITIONAL_PANEL_TYPES_ENABLED = 'SET_ADDITIONAL_PANEL_TYPES_ENABLED';
export const SET_ALL_DASHBOARDS = 'SET_ALL_DASHBOARDS';
export const SET_ENDPOINTS = 'SET_ENDPOINTS';
export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE';
......
......@@ -75,6 +75,7 @@ export default {
state.deploymentsEndpoint = endpoints.deploymentsEndpoint;
state.dashboardEndpoint = endpoints.dashboardEndpoint;
state.currentDashboard = endpoints.currentDashboard;
state.projectPath = endpoints.projectPath;
},
[types.SET_DASHBOARD_ENABLED](state, enabled) {
state.useDashboardEndpoint = enabled;
......@@ -92,4 +93,7 @@ export default {
[types.SET_ALL_DASHBOARDS](state, dashboards) {
state.allDashboards = dashboards;
},
[types.SET_ADDITIONAL_PANEL_TYPES_ENABLED](state, enabled) {
state.additionalPanelTypesEnabled = enabled;
},
};
......@@ -9,6 +9,7 @@ export default () => ({
dashboardEndpoint: invalidUrl,
useDashboardEndpoint: false,
multipleDashboardsEnabled: false,
additionalPanelTypesEnabled: false,
emptyState: 'gettingStarted',
showEmptyState: true,
groups: [],
......@@ -17,4 +18,5 @@ export default () => ({
metricsWithData: [],
allDashboards: [],
currentDashboard: null,
projectPath: null,
});
......@@ -69,13 +69,26 @@ export const sortMetrics = metrics =>
.sortBy('weight')
.value();
export const normalizeQueryResult = timeSeries => ({
...timeSeries,
values: timeSeries.values.map(([timestamp, value]) => [
new Date(timestamp * 1000).toISOString(),
Number(value),
]),
});
export const normalizeQueryResult = timeSeries => {
let normalizedResult = {};
if (timeSeries.values) {
normalizedResult = {
...timeSeries,
values: timeSeries.values.map(([timestamp, value]) => [
new Date(timestamp * 1000).toISOString(),
Number(value),
]),
};
} else if (timeSeries.value) {
normalizedResult = {
...timeSeries,
value: [new Date(timeSeries.value[0] * 1000).toISOString(), Number(timeSeries.value[1])],
};
}
return normalizedResult;
};
export const normalizeMetrics = metrics => {
const groupedMetrics = groupQueriesByChartInfo(metrics);
......
......@@ -30,4 +30,28 @@ export const getTimeDiff = selectedTimeWindow => {
return { start, end };
};
/**
* This method is used to validate if the graph data format for a chart component
* that needs a time series as a response from a prometheus query (query_range) is
* of a valid format or not.
* @param {Object} graphData the graph data response from a prometheus request
* @returns {boolean} whether the graphData format is correct
*/
export const graphDataValidatorForValues = (isValues, graphData) => {
const responseValueKeyName = isValues ? 'value' : 'values';
return (
Array.isArray(graphData.queries) &&
graphData.queries.filter(query => {
if (Array.isArray(query.result)) {
return (
query.result.filter(res => Array.isArray(res[responseValueKeyName])).length ===
query.result.length
);
}
return false;
}).length === graphData.queries.length
);
};
export default {};
......@@ -9,9 +9,6 @@ export default {
const config = filter !== undefined ? { params: { notes_filter: filter } } : null;
return Vue.http.get(endpoint, config);
},
deleteNote(endpoint) {
return Vue.http.delete(endpoint);
},
replyToDiscussion(endpoint, data) {
return Vue.http.post(endpoint, data, { emulateJSON: true });
},
......
......@@ -62,7 +62,7 @@ export const updateDiscussion = ({ commit, state }, discussion) => {
};
export const deleteNote = ({ commit, dispatch, state }, note) =>
service.deleteNote(note.path).then(() => {
axios.delete(note.path).then(() => {
const discussion = state.discussions.find(({ id }) => id === note.discussion_id);
commit(types.DELETE_NOTE, note);
......
import FilterableList from '~/filterable_list';
export default class ProjectsFilterableList extends FilterableList {
getFilterEndpoint() {
return this.getPagePath().replace('/projects?', '/projects.json?');
}
}
import FilterableList from './filterable_list';
import ProjectsFilterableList from './projects/projects_filterable_list';
/**
* Makes search request for projects when user types a value in the search input.
......@@ -11,7 +11,7 @@ export default class ProjectsList {
const holder = document.querySelector('.js-projects-list-holder');
if (form && filter && holder) {
const list = new FilterableList(form, filter, holder);
const list = new ProjectsFilterableList(form, filter, holder);
list.initSearch();
}
}
......
......@@ -63,7 +63,8 @@
margin-top: 11px;
}
.dropdown-toggle {
.dropdown-toggle,
.confidential-merge-request-fork-group .dropdown-toggle {
padding: 6px 8px 6px 10px;
background-color: $white-light;
color: $gl-text-color;
......@@ -288,7 +289,7 @@
padding: 0 1px;
a,
button:not(.dropdown-toggle,.ci-action-icon-container),
button,
.menu-item {
@include dropdown-link;
}
......
......@@ -90,6 +90,20 @@ body.modal-open {
.modal {
background-color: $black-transparent;
.modal-content {
border-radius: $modal-border-radius;
*:first-child {
border-top-left-radius: $modal-border-radius;
border-top-right-radius: $modal-border-radius;
}
*:last-child {
border-bottom-left-radius: $modal-border-radius;
border-bottom-right-radius: $modal-border-radius;
}
}
@include media-breakpoint-up(sm) {
.modal-dialog {
margin: 64px auto;
......
......@@ -806,6 +806,7 @@ Modals
*/
$modal-body-height: 80px;
$modal-border-color: #e9ecef;
$modal-border-radius: 0.25rem;
$priority-label-empty-state-width: 114px;
......
......@@ -50,7 +50,7 @@ module Projects
end
def cycle_analytics
@cycle_analytics ||= ::CycleAnalytics.new(project, options(events_params))
@cycle_analytics ||= ::CycleAnalytics::ProjectLevel.new(project, options: options(events_params))
end
def events_params
......
......@@ -9,7 +9,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
before_action :authorize_read_cycle_analytics!
def show
@cycle_analytics = ::CycleAnalytics.new(@project, options(cycle_analytics_params))
@cycle_analytics = ::CycleAnalytics::ProjectLevel.new(@project, options: options(cycle_analytics_params))
@cycle_analytics_no_data = @cycle_analytics.no_stats?
......
......@@ -13,6 +13,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do
push_frontend_feature_flag(:environment_metrics_use_prometheus_endpoint)
push_frontend_feature_flag(:environment_metrics_show_multiple_dashboards)
push_frontend_feature_flag(:environment_metrics_additional_panel_types)
push_frontend_feature_flag(:prometheus_computed_alerts)
end
......
......@@ -3,7 +3,7 @@
require 'nokogiri'
module MarkupHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::TextHelper
include ::Gitlab::ActionViewOutput::Context
def plain?(filename)
......@@ -154,9 +154,7 @@ module MarkupHelper
elsif asciidoc?(file_name)
asciidoc_unsafe(text, context)
elsif plain?(file_name)
content_tag :pre, class: 'plain-readme' do
text
end
plain_unsafe(text)
else
other_markup_unsafe(file_name, text, context)
end
......@@ -271,6 +269,12 @@ module MarkupHelper
Gitlab::Asciidoc.render(text, context)
end
def plain_unsafe(text)
content_tag :pre, class: 'plain-readme' do
text
end
end
def other_markup_unsafe(file_name, text, context = {})
Gitlab::OtherMarkup.render(file_name, text, context)
end
......
......@@ -12,6 +12,6 @@ class ChatTeam < ApplicationRecord
# Either the group is not found, or the user doesn't have the proper
# access on the mattermost instance. In the first case, we're done either way
# in the latter case, we can't recover by retrying, so we just log what happened
Rails.logger.error("Mattermost team deletion failed: #{e}")
Rails.logger.error("Mattermost team deletion failed: #{e}") # rubocop:disable Gitlab/RailsLogger
end
end
......@@ -266,7 +266,7 @@ module Ci
begin
Ci::Build.retry(build, build.user)
rescue Gitlab::Access::AccessDeniedError => ex
Rails.logger.error "Unable to auto-retry job #{build.id}: #{ex}"
Rails.logger.error "Unable to auto-retry job #{build.id}: #{ex}" # rubocop:disable Gitlab/RailsLogger
end
end
end
......
......@@ -49,7 +49,7 @@ module CacheableAttributes
current_without_cache.tap { |current_record| current_record&.cache! }
rescue => e
if Rails.env.production?
Rails.logger.warn("Cached record for #{name} couldn't be loaded, falling back to uncached record: #{e}")
Rails.logger.warn("Cached record for #{name} couldn't be loaded, falling back to uncached record: #{e}") # rubocop:disable Gitlab/RailsLogger
else
raise e
end
......
......@@ -64,7 +64,7 @@ module Storage
unless gitlab_shell.mv_namespace(repository_storage, full_path_before_last_save, full_path)
Rails.logger.error "Exception moving path #{repository_storage} from #{full_path_before_last_save} to #{full_path}"
Rails.logger.error "Exception moving path #{repository_storage} from #{full_path_before_last_save} to #{full_path}" # rubocop:disable Gitlab/RailsLogger
# if we cannot move namespace directory we should rollback
# db changes in order to prevent out of sync between db and fs
......
# frozen_string_literal: true
class CycleAnalytics
STAGES = %i[issue plan code test review staging production].freeze
def initialize(project, options)
@project = project
@options = options
end
def all_medians_per_stage
STAGES.each_with_object({}) do |stage_name, medians_per_stage|
medians_per_stage[stage_name] = self[stage_name].median
end
end
def summary
@summary ||= ::Gitlab::CycleAnalytics::StageSummary.new(@project,
from: @options[:from],
current_user: @options[:current_user]).data
end
def stats
@stats ||= stats_per_stage
end
def no_stats?
stats.all? { |hash| hash[:value].nil? }
end
def permissions(user:)
Gitlab::CycleAnalytics::Permissions.get(user: user, project: @project)
end
def [](stage_name)
Gitlab::CycleAnalytics::Stage[stage_name].new(project: @project, options: @options)
end
private
def stats_per_stage
STAGES.map do |stage_name|
self[stage_name].as_json
end
end
end
# frozen_string_literal: true
module CycleAnalytics
class Base
STAGES = %i[issue plan code test review staging production].freeze
def all_medians_by_stage
STAGES.each_with_object({}) do |stage_name, medians_per_stage|
medians_per_stage[stage_name] = self[stage_name].median
end
end
def stats
@stats ||= STAGES.map do |stage_name|
self[stage_name].as_json
end
end
def no_stats?
stats.all? { |hash| hash[:value].nil? }
end
def [](stage_name)
Gitlab::CycleAnalytics::Stage[stage_name].new(project: @project, options: @options)
end
end
end
# frozen_string_literal: true
module CycleAnalytics
class ProjectLevel < Base
attr_reader :project, :options
def initialize(project, options:)
@project = project
@options = options
end
def summary
@summary ||= ::Gitlab::CycleAnalytics::StageSummary.new(project,
from: options[:from],
current_user: options[:current_user]).data
end
def permissions(user:)
Gitlab::CycleAnalytics::Permissions.get(user: user, project: project)
end
end
end
......@@ -40,7 +40,7 @@ class EnvironmentStatus
end
def changes
return [] if project.route_map_for(sha).nil?
return [] unless has_route_map?
changed_files.map { |file| build_change(file) }.compact
end
......@@ -50,6 +50,10 @@ class EnvironmentStatus
.merge_request_diff_files.where(deleted_file: false)
end
def has_route_map?
project.route_map_for(sha).present?
end
private
PAGE_EXTENSIONS = /\A\.(s?html?|php|asp|cgi|pl)\z/i.freeze
......
......@@ -784,6 +784,7 @@ class Project < ApplicationRecord
job_id
end
# rubocop:disable Gitlab/RailsLogger
def log_import_activity(job_id, type: :import)
job_type = type.to_s.capitalize
......@@ -793,6 +794,7 @@ class Project < ApplicationRecord
Rails.logger.error("#{job_type} job failed to create for #{full_path}.")
end
end
# rubocop:enable Gitlab/RailsLogger
def reset_cache_and_import_attrs
run_after_commit do
......@@ -1665,6 +1667,7 @@ class Project < ApplicationRecord
end
# rubocop: enable CodeReuse/ServiceClass
# rubocop:disable Gitlab/RailsLogger
def write_repository_config(gl_full_path: full_path)
# We'd need to keep track of project full path otherwise directory tree
# created with hashed storage enabled cannot be usefully imported using
......@@ -1674,6 +1677,7 @@ class Project < ApplicationRecord
Rails.logger.error("Error writing to .git/config for project #{full_path} (#{id}): #{e.message}.")
nil
end
# rubocop:enable Gitlab/RailsLogger
def after_import
repository.after_import
......@@ -1715,6 +1719,7 @@ class Project < ApplicationRecord
@pipeline_status ||= Gitlab::Cache::Ci::ProjectPipelineStatus.load_for_project(self)
end
# rubocop:disable Gitlab/RailsLogger
def add_export_job(current_user:, after_export_strategy: nil, params: {})
job_id = ProjectExportWorker.perform_async(current_user.id, self.id, after_export_strategy, params)
......@@ -1724,6 +1729,7 @@ class Project < ApplicationRecord
Rails.logger.error "Export job failed to start for project ID #{self.id}"
end
end
# rubocop:enable Gitlab/RailsLogger
def import_export_shared
@import_export_shared ||= Gitlab::ImportExport::Shared.new(self)
......@@ -1914,9 +1920,8 @@ class Project < ApplicationRecord
@route_maps_by_commit ||= Hash.new do |h, sha|
h[sha] = begin
data = repository.route_map_for(sha)
next unless data
Gitlab::RouteMap.new(data)
Gitlab::RouteMap.new(data) if data
rescue Gitlab::RouteMap::FormatError
nil
end
......
......@@ -65,7 +65,7 @@ class ProjectImportState < ApplicationRecord
update_column(:last_error, sanitized_message)
rescue ActiveRecord::ActiveRecordError => e
Rails.logger.error("Error setting import status to failed: #{e.message}. Original error: #{sanitized_message}")
Rails.logger.error("Error setting import status to failed: #{e.message}. Original error: #{sanitized_message}") # rubocop:disable Gitlab/RailsLogger
ensure
@errors = original_errors
end
......
......@@ -3,68 +3,7 @@
class PrometheusMetric < ApplicationRecord
belongs_to :project, validate: true, inverse_of: :prometheus_metrics
enum group: {
# built-in groups
nginx_ingress_vts: -1,
ha_proxy: -2,
aws_elb: -3,
nginx: -4,
kubernetes: -5,
nginx_ingress: -6,
# custom/user groups
business: 0,
response: 1,
system: 2
}
GROUP_DETAILS = {
# built-in groups
nginx_ingress_vts: {
group_title: _('Response metrics (NGINX Ingress VTS)'),
required_metrics: %w(nginx_upstream_responses_total nginx_upstream_response_msecs_avg),
priority: 10
}.freeze,
nginx_ingress: {
group_title: _('Response metrics (NGINX Ingress)'),
required_metrics: %w(nginx_ingress_controller_requests nginx_ingress_controller_ingress_upstream_latency_seconds_sum),
priority: 10
}.freeze,
ha_proxy: {
group_title: _('Response metrics (HA Proxy)'),
required_metrics: %w(haproxy_frontend_http_requests_total haproxy_frontend_http_responses_total),
priority: 10
}.freeze,
aws_elb: {
group_title: _('Response metrics (AWS ELB)'),
required_metrics: %w(aws_elb_request_count_sum aws_elb_latency_average aws_elb_httpcode_backend_5_xx_sum),
priority: 10
}.freeze,
nginx: {
group_title: _('Response metrics (NGINX)'),
required_metrics: %w(nginx_server_requests nginx_server_requestMsec),
priority: 10
}.freeze,
kubernetes: {
group_title: _('System metrics (Kubernetes)'),
required_metrics: %w(container_memory_usage_bytes container_cpu_usage_seconds_total),
priority: 5
}.freeze,
# custom/user groups
business: {
group_title: _('Business metrics (Custom)'),
priority: 0
}.freeze,
response: {
group_title: _('Response metrics (Custom)'),
priority: -5
}.freeze,
system: {
group_title: _('System metrics (Custom)'),
priority: -10
}.freeze
}.freeze
enum group: PrometheusMetricEnums.groups
validates :title, presence: true
validates :query, presence: true
......@@ -121,7 +60,7 @@ class PrometheusMetric < ApplicationRecord
private
def group_details(group)
GROUP_DETAILS.fetch(group.to_sym)
PrometheusMetricEnums.group_details.fetch(group.to_sym)
end
end
......
# frozen_string_literal: true
module PrometheusMetricEnums
def self.groups
{
# built-in groups
nginx_ingress_vts: -1,
ha_proxy: -2,
aws_elb: -3,
nginx: -4,
kubernetes: -5,
nginx_ingress: -6,
# custom/user groups
business: 0,
response: 1,
system: 2
}
end
def self.group_details
{
# built-in groups
nginx_ingress_vts: {
group_title: _('Response metrics (NGINX Ingress VTS)'),
required_metrics: %w(nginx_upstream_responses_total nginx_upstream_response_msecs_avg),
priority: 10
}.freeze,
nginx_ingress: {
group_title: _('Response metrics (NGINX Ingress)'),
required_metrics: %w(nginx_ingress_controller_requests nginx_ingress_controller_ingress_upstream_latency_seconds_sum),
priority: 10
}.freeze,
ha_proxy: {
group_title: _('Response metrics (HA Proxy)'),
required_metrics: %w(haproxy_frontend_http_requests_total haproxy_frontend_http_responses_total),
priority: 10
}.freeze,
aws_elb: {
group_title: _('Response metrics (AWS ELB)'),
required_metrics: %w(aws_elb_request_count_sum aws_elb_latency_average aws_elb_httpcode_backend_5_xx_sum),
priority: 10
}.freeze,
nginx: {
group_title: _('Response metrics (NGINX)'),
required_metrics: %w(nginx_server_requests nginx_server_requestMsec),
priority: 10
}.freeze,
kubernetes: {
group_title: _('System metrics (Kubernetes)'),
required_metrics: %w(container_memory_usage_bytes container_cpu_usage_seconds_total),
priority: 5
}.freeze,
# custom/user groups
business: {
group_title: _('Business metrics (Custom)'),
priority: 0
}.freeze,
response: {
group_title: _('Response metrics (Custom)'),
priority: -5
}.freeze,
system: {
group_title: _('System metrics (Custom)'),
priority: -10
}.freeze
}.freeze
end
end
PrometheusMetricEnums.prepend(EE::PrometheusMetricEnums)
......@@ -273,7 +273,7 @@ class Repository
# This will still fail if the file is corrupted (e.g. 0 bytes)
raw_repository.write_ref(keep_around_ref_name(sha), sha)
rescue Gitlab::Git::CommandError => ex
Rails.logger.error "Unable to create keep-around reference for repository #{disk_path}: #{ex}"
Rails.logger.error "Unable to create keep-around reference for repository #{disk_path}: #{ex}" # rubocop:disable Gitlab/RailsLogger
end
end
......@@ -934,6 +934,7 @@ class Repository
async_remove_remote(remote_name) if tmp_remote_name
end
# rubocop:disable Gitlab/RailsLogger
def async_remove_remote(remote_name)
return unless remote_name
......@@ -947,6 +948,7 @@ class Repository
job_id
end
# rubocop:enable Gitlab/RailsLogger
def fetch_source_branch!(source_repository, source_branch, local_ref)
raw_repository.fetch_source_branch!(source_repository.raw_repository, source_branch, local_ref)
......
......@@ -106,7 +106,7 @@ class SshHostKey
if status.success? && !errors.present?
{ known_hosts: known_hosts }
else
Rails.logger.debug("Failed to detect SSH host keys for #{id}: #{errors}")
Rails.logger.debug("Failed to detect SSH host keys for #{id}: #{errors}") # rubocop:disable Gitlab/RailsLogger
{ error: 'Failed to detect SSH host keys' }
end
......
......@@ -41,7 +41,7 @@ module Storage
gitlab_shell.mv_repository(repository_storage, "#{old_full_path}.wiki", "#{new_full_path}.wiki")
return true
rescue => e
Rails.logger.error "Exception renaming #{old_full_path} -> #{new_full_path}: #{e}"
Rails.logger.error "Exception renaming #{old_full_path} -> #{new_full_path}: #{e}" # rubocop:disable Gitlab/RailsLogger
# Returning false does not rollback after_* transaction but gives
# us information about failing some of tasks
return false
......
......@@ -7,7 +7,7 @@ module Uploads
attr_reader :logger
def initialize(logger: nil)
@logger ||= Rails.logger
@logger ||= Rails.logger # rubocop:disable Gitlab/RailsLogger
end
def delete_keys_async(keys_to_delete)
......
......@@ -25,7 +25,7 @@ class AkismetService
is_spam, is_blatant = akismet_client.check(options[:ip_address], options[:user_agent], params)
is_spam || is_blatant
rescue => e
Rails.logger.error("Unable to connect to Akismet: #{e}, skipping check")
Rails.logger.error("Unable to connect to Akismet: #{e}, skipping check") # rubocop:disable Gitlab/RailsLogger
false
end
end
......@@ -63,7 +63,7 @@ class AkismetService
akismet_client.public_send(type, options[:ip_address], options[:user_agent], params) # rubocop:disable GitlabSecurity/PublicSend
true
rescue => e
Rails.logger.error("Unable to connect to Akismet: #{e}, skipping!")
Rails.logger.error("Unable to connect to Akismet: #{e}, skipping!") # rubocop:disable Gitlab/RailsLogger
false
end
end
......
......@@ -24,11 +24,11 @@ module Ci
def archive_error(error, job)
failed_archive_counter.increment
Rails.logger.error "Failed to archive trace. id: #{job.id} message: #{error.message}"
Rails.logger.error "Failed to archive trace. id: #{job.id} message: #{error.message}" # rubocop:disable Gitlab/RailsLogger
Gitlab::Sentry
.track_exception(error,
issue_url: 'https://gitlab.com/gitlab-org/gitlab-ce/issues/51502',
issue_url: 'https://gitlab.com/gitlab-org/gitlab-ce/issues/51502',
extra: { job_id: job.id })
end
end
......
......@@ -58,6 +58,6 @@ module ExclusiveLeaseGuard
end
def log_error(message, extra_args = {})
Rails.logger.error(message)
Rails.logger.error(message) # rubocop:disable Gitlab/RailsLogger
end
end
......@@ -6,7 +6,7 @@ module Groups
def async_execute
job_id = GroupDestroyWorker.perform_async(group.id, current_user.id)
Rails.logger.info("User #{current_user.id} scheduled a deletion of group ID #{group.id} with job ID #{job_id}")
Rails.logger.info("User #{current_user.id} scheduled a deletion of group ID #{group.id} with job ID #{job_id}") # rubocop:disable Gitlab/RailsLogger
end
# rubocop: disable CodeReuse/ActiveRecord
......
......@@ -20,7 +20,7 @@ module Labels
label.save
label
else
Rails.logger.warn("target_params should contain :project or :group or :template, actual value: #{target_params}")
Rails.logger.warn("target_params should contain :project or :group or :template, actual value: #{target_params}") # rubocop:disable Gitlab/RailsLogger
end
end
end
......
......@@ -113,12 +113,12 @@ module MergeRequests
end
def handle_merge_error(log_message:, save_message_on_model: false)
Rails.logger.error("MergeService ERROR: #{merge_request_info} - #{log_message}")
Rails.logger.error("MergeService ERROR: #{merge_request_info} - #{log_message}") # rubocop:disable Gitlab/RailsLogger
@merge_request.update(merge_error: log_message) if save_message_on_model
end
def log_info(message)
@logger ||= Rails.logger
@logger ||= Rails.logger # rubocop:disable Gitlab/RailsLogger
@logger.info("#{merge_request_info} - #{message}")
end
......
......@@ -13,7 +13,7 @@ module Projects
repository.delete_all_refs_except(RESERVED_REF_PREFIXES)
end
rescue Projects::HousekeepingService::LeaseTaken => e
Rails.logger.info(
Rails.logger.info( # rubocop:disable Gitlab/RailsLogger
"Could not perform housekeeping for project #{@project.full_path} (#{@project.id}): #{e}")
end
......
......@@ -151,7 +151,7 @@ module Projects
log_message = message.dup
log_message << " Project ID: #{@project.id}" if @project&.id
Rails.logger.error(log_message)
Rails.logger.error(log_message) # rubocop:disable Gitlab/RailsLogger
if @project && @project.persisted? && @project.import_state
@project.import_state.mark_as_failed(message)
......
......@@ -18,7 +18,7 @@ module Projects
schedule_stale_repos_removal
job_id = ProjectDestroyWorker.perform_async(project.id, current_user.id, params)
Rails.logger.info("User #{current_user.id} scheduled destruction of project #{project.full_path} with job ID #{job_id}")
Rails.logger.info("User #{current_user.id} scheduled destruction of project #{project.full_path} with job ID #{job_id}") # rubocop:disable Gitlab/RailsLogger
end
def execute
......
......@@ -5,7 +5,7 @@ module Projects
class MigrateAttachmentsService < BaseAttachmentService
def initialize(project, old_disk_path, logger: nil)
@project = project
@logger = logger || Rails.logger
@logger = logger || Rails.logger # rubocop:disable Gitlab/RailsLogger
@old_disk_path = old_disk_path
@skipped = false
end
......
......@@ -5,7 +5,7 @@ module Projects
class RollbackAttachmentsService < BaseAttachmentService
def initialize(project, logger: nil)
@project = project
@logger = logger || Rails.logger
@logger = logger || Rails.logger # rubocop:disable Gitlab/RailsLogger
@old_disk_path = project.disk_path
end
......
......@@ -8,7 +8,7 @@ module Projects
def initialize(project, old_disk_path, logger: nil)
@project = project
@old_disk_path = old_disk_path
@logger = logger || Rails.logger
@logger = logger || Rails.logger # rubocop:disable Gitlab/RailsLogger
end
def execute
......
......@@ -62,7 +62,7 @@ module Projects
end
def cleanup_and_notify_error
Rails.logger.error("Import/Export - Project #{project.name} with ID: #{project.id} export error - #{@shared.errors.join(', ')}")
Rails.logger.error("Import/Export - Project #{project.name} with ID: #{project.id} export error - #{@shared.errors.join(', ')}") # rubocop:disable Gitlab/RailsLogger
FileUtils.rm_rf(@shared.export_path)
......@@ -76,7 +76,7 @@ module Projects
end
def notify_success
Rails.logger.info("Import/Export - Project #{project.name} with ID: #{project.id} successfully exported")
Rails.logger.info("Import/Export - Project #{project.name} with ID: #{project.id} successfully exported") # rubocop:disable Gitlab/RailsLogger
end
def notify_error
......
......@@ -15,7 +15,7 @@ module Projects
def propagate
return unless @template.active?
Rails.logger.info("Propagating services for template #{@template.id}")
Rails.logger.info("Propagating services for template #{@template.id}") # rubocop:disable Gitlab/RailsLogger
propagate_projects_with_template
end
......
......@@ -5,7 +5,7 @@ module Projects
def execute
return unless project
Rails.logger.info("Updating statistics for project #{project.id}")
Rails.logger.info("Updating statistics for project #{project.id}") # rubocop:disable Gitlab/RailsLogger
project.statistics.refresh!(only: statistics.map(&:to_sym))
end
......
......@@ -28,7 +28,7 @@ class SubmitUsagePingService
true
rescue Gitlab::HTTP::Error => e
Rails.logger.info "Unable to contact GitLab, Inc.: #{e}"
Rails.logger.info "Unable to contact GitLab, Inc.: #{e}" # rubocop:disable Gitlab/RailsLogger
false
end
......
......@@ -53,7 +53,7 @@ class WebHookService
error_message: e.to_s
)
Rails.logger.error("WebHook Error => #{e}")
Rails.logger.error("WebHook Error => #{e}") # rubocop:disable Gitlab/RailsLogger
{
status: :error,
......
......@@ -98,7 +98,7 @@ class FileMover
end
def revert
Rails.logger.warn("Markdown not updated, file move reverted for #{to_model}")
Rails.logger.warn("Markdown not updated, file move reverted for #{to_model}") # rubocop:disable Gitlab/RailsLogger
if temp_file_uploader.file_storage?
FileUtils.move(file_path, temp_file_path)
......
......@@ -8,7 +8,7 @@
- if current_user
.page-title-controls
= render 'shared/new_project_item_select',
path: 'milestones/new', label: 'New milestone',
path: '-/milestones/new', label: 'New milestone',
include_groups: true, type: :milestones
.top-area
......
......@@ -24,4 +24,4 @@
- if current_user_menu?(:sign_out)
%li.divider
%li
= link_to _("Sign out"), destroy_user_session_path, class: "sign-out-link"
= link_to _("Sign out"), destroy_user_session_path, class: "sign-out-link qa-sign-out-link"
= form.label :assignee_id, "Assignee", class: "col-form-label #{has_due_date ? "col-lg-4" : "col-sm-2"}"
= form.label :assignee_id, "Assignee", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
.col-sm-10{ class: ("col-md-8" if has_due_date) }
.issuable-form-select-holder.selectbox
- issuable.assignees.each do |assignee|
......
......@@ -27,6 +27,6 @@ module NewIssuable
# rubocop: enable CodeReuse/ActiveRecord
def log_error(record_class, record_id)
Rails.logger.error("#{self.class}: couldn't find #{record_class} with ID=#{record_id}, skipping job")
Rails.logger.error("#{self.class}: couldn't find #{record_class} with ID=#{record_id}, skipping job") # rubocop:disable Gitlab/RailsLogger
end
end
......@@ -22,7 +22,7 @@ class CreateGpgSignatureWorker
commits.each do |commit|
Gitlab::Gpg::Commit.new(commit).signature
rescue => e
Rails.logger.error("Failed to create signature for commit #{commit.id}. Error: #{e.message}")
Rails.logger.error("Failed to create signature for commit #{commit.id}. Error: #{e.message}") # rubocop:disable Gitlab/RailsLogger
end
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -9,6 +9,6 @@ class DeleteUserWorker
Users::DestroyService.new(current_user).execute(delete_user, options.symbolize_keys)
rescue Gitlab::Access::AccessDeniedError => e
Rails.logger.warn("User could not be destroyed: #{e}")
Rails.logger.warn("User could not be destroyed: #{e}") # rubocop:disable Gitlab/RailsLogger
end
end
......@@ -16,7 +16,7 @@ class EmailReceiverWorker
private
def handle_failure(raw, error)
Rails.logger.warn("Email can not be processed: #{error}\n\n#{raw}")
Rails.logger.warn("Email can not be processed: #{error}\n\n#{raw}") # rubocop:disable Gitlab/RailsLogger
return unless raw.present?
......
......@@ -18,7 +18,7 @@ class ExpireBuildArtifactsWorker
# rubocop: disable CodeReuse/ActiveRecord
def perform_legacy_artifacts_removal
Rails.logger.info 'Scheduling removal of build artifacts'
Rails.logger.info 'Scheduling removal of build artifacts' # rubocop:disable Gitlab/RailsLogger
build_ids = Ci::Build.with_expired_artifacts.pluck(:id)
build_ids = build_ids.map { |build_id| [build_id] }
......
......@@ -12,7 +12,7 @@ class ExpireBuildInstanceArtifactsWorker
return unless build&.project && !build.project.pending_delete
Rails.logger.info "Removing artifacts for build #{build.id}..."
Rails.logger.info "Removing artifacts for build #{build.id}..." # rubocop:disable Gitlab/RailsLogger
build.erase_erasable_artifacts!
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -11,7 +11,7 @@ class NewNoteWorker
NotificationService.new.new_note(note) unless skip_notification?(note)
Notes::PostProcessService.new(note).execute
else
Rails.logger.error("NewNoteWorker: couldn't find note with ID=#{note_id}, skipping job")
Rails.logger.error("NewNoteWorker: couldn't find note with ID=#{note_id}, skipping job") # rubocop:disable Gitlab/RailsLogger
end
end
......
......@@ -37,6 +37,7 @@ module ObjectStorage
end
end
# rubocop:disable Gitlab/RailsLogger
def report!(results)
success, failures = results.partition(&:success?)
......@@ -45,6 +46,7 @@ module ObjectStorage
raise MigrationFailures.new(failures.map(&:error)) if failures.any?
end
# rubocop:enable Gitlab/RailsLogger
def header(success, failures)
_("Migrated %{success_count}/%{total_count} files.") % { success_count: success.count, total_count: success.count + failures.count }
......@@ -98,7 +100,7 @@ module ObjectStorage
report!(results)
rescue SanityCheckError => e
# do not retry: the job is insane
Rails.logger.warn "#{self.class}: Sanity check error (#{e.message})"
Rails.logger.warn "#{self.class}: Sanity check error (#{e.message})" # rubocop:disable Gitlab/RailsLogger
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -35,7 +35,7 @@ class RepositoryForkWorker
def start_fork(project)
return true if start(project.import_state)
Rails.logger.info("Project #{project.full_path} was in inconsistent state (#{project.import_status}) while forking.")
Rails.logger.info("Project #{project.full_path} was in inconsistent state (#{project.import_status}) while forking.") # rubocop:disable Gitlab/RailsLogger
false
end
end
......@@ -36,7 +36,7 @@ class RepositoryImportWorker
def start_import
return true if start(project.import_state)
Rails.logger.info("Project #{project.full_path} was in inconsistent state (#{project.import_status}) while importing.")
Rails.logger.info("Project #{project.full_path} was in inconsistent state (#{project.import_status}) while importing.") # rubocop:disable Gitlab/RailsLogger
false
end
......
......@@ -45,6 +45,6 @@ class RepositoryUpdateRemoteMirrorWorker
def fail_remote_mirror(remote_mirror, message)
remote_mirror.mark_as_failed(message)
Rails.logger.error(message)
Rails.logger.error(message) # rubocop:disable Gitlab/RailsLogger
end
end
......@@ -30,6 +30,7 @@ class RunPipelineScheduleWorker
private
# rubocop:disable Gitlab/RailsLogger
def error(schedule, error)
failed_creation_counter.increment
......@@ -41,6 +42,7 @@ class RunPipelineScheduleWorker
issue_url: 'https://gitlab.com/gitlab-org/gitlab-ce/issues/41231',
extra: { schedule_id: schedule.id })
end
# rubocop:enable Gitlab/RailsLogger
def failed_creation_counter
@failed_creation_counter ||=
......
......@@ -14,7 +14,7 @@ class StuckCiJobsWorker
def perform
return unless try_obtain_lease
Rails.logger.info "#{self.class}: Cleaning stuck builds"
Rails.logger.info "#{self.class}: Cleaning stuck builds" # rubocop:disable Gitlab/RailsLogger
drop :running, BUILD_RUNNING_OUTDATED_TIMEOUT, 'ci_builds.updated_at < ?', :stuck_or_timeout_failure
drop :pending, BUILD_PENDING_OUTDATED_TIMEOUT, 'ci_builds.updated_at < ?', :stuck_or_timeout_failure
......@@ -66,7 +66,7 @@ class StuckCiJobsWorker
# rubocop: enable CodeReuse/ActiveRecord
def drop_build(type, build, status, timeout, reason)
Rails.logger.info "#{self.class}: Dropping #{type} build #{build.id} for runner #{build.runner_id} (status: #{status}, timeout: #{timeout}, reason: #{reason})"
Rails.logger.info "#{self.class}: Dropping #{type} build #{build.id} for runner #{build.runner_id} (status: #{status}, timeout: #{timeout}, reason: #{reason})" # rubocop:disable Gitlab/RailsLogger
Gitlab::OptimisticLocking.retry_lock(build, 3) do |b|
b.drop(reason)
end
......
......@@ -38,7 +38,7 @@ class StuckImportJobsWorker
completed_import_states = enqueued_import_states_with_jid.where(id: completed_import_state_ids)
completed_import_state_jids = completed_import_states.map { |import_state| import_state.jid }.join(', ')
Rails.logger.info("Marked stuck import jobs as failed. JIDs: #{completed_import_state_jids}")
Rails.logger.info("Marked stuck import jobs as failed. JIDs: #{completed_import_state_jids}") # rubocop:disable Gitlab/RailsLogger
completed_import_states.each do |import_state|
import_state.mark_as_failed(error_message)
......
......@@ -5,7 +5,7 @@ class StuckMergeJobsWorker
include CronjobQueue
def self.logger
Rails.logger
Rails.logger # rubocop:disable Gitlab/RailsLogger
end
# rubocop: disable CodeReuse/ActiveRecord
......
......@@ -5,7 +5,7 @@ class TrendingProjectsWorker
include CronjobQueue
def perform
Rails.logger.info('Refreshing trending projects')
Rails.logger.info('Refreshing trending projects') # rubocop:disable Gitlab/RailsLogger
TrendingProject.refresh!
end
......
......@@ -27,7 +27,7 @@ class UpdateMergeRequestsWorker
"ref=#{ref}"
].join(',')
Rails.logger.info("UpdateMergeRequestsWorker#perform #{args_log}") if time.real > LOG_TIME_THRESHOLD
Rails.logger.info("UpdateMergeRequestsWorker#perform #{args_log}") if time.real > LOG_TIME_THRESHOLD # rubocop:disable Gitlab/RailsLogger
end
# rubocop: enable CodeReuse/ActiveRecord
end
......@@ -8,6 +8,6 @@ class UploadChecksumWorker
upload.calculate_checksum!
upload.save!
rescue ActiveRecord::RecordNotFound
Rails.logger.error("UploadChecksumWorker: couldn't find upload #{upload_id}, skipping")
Rails.logger.error("UploadChecksumWorker: couldn't find upload #{upload_id}, skipping") # rubocop:disable Gitlab/RailsLogger
end
end
---
title: Fixed back navigation for projects filter
merge_request: 30373
author:
type: fixed
---
title: Fix wrong URL when creating milestones from instance milestones dashboard
merge_request: 30512
author:
type: fixed
---
title: Fixed incorrect line wrap for assignee label in issues
merge_request: 30523
author: Marc Schwede
type: fixed
---
title: Improve performance of fetching environments statuses
merge_request: 30560
author:
type: performance
---
title: Expose placeholder element for metrics charts in GFM
merge_request: 29861
author:
type: added
---
title: Upgrade to Gitaly v1.52.0
merge_request: 30568
author:
type: changed
---
title: Modify cycle analytics on project level
merge_request: 30356
author:
type: changed
---
title: Extract clair version as CLAIR_EXECUTABLE_VERSION variable and update clair
executable from v8 to v11
merge_request: 30396
author:
type: changed
---
title: Remove deleteNote from notes service
merge_request: 30537
author: Frank van Rest
type: other
......@@ -55,7 +55,7 @@ if Settings.ldap['enabled'] || Rails.env.test?
server['tls_options'] ||= {}
if server['ssl_version'] || server['ca_file']
Rails.logger.warn 'DEPRECATED: LDAP options `ssl_version` and `ca_file` should be nested within `tls_options`'
Rails.logger.warn 'DEPRECATED: LDAP options `ssl_version` and `ca_file` should be nested within `tls_options`' # rubocop:disable Gitlab/RailsLogger
end
if server['ssl_version']
......
......@@ -17,7 +17,7 @@ def prometheus_default_multiproc_dir
end
Prometheus::Client.configure do |config|
config.logger = Rails.logger
config.logger = Rails.logger # rubocop:disable Gitlab/RailsLogger
config.initial_mmap_file_size = 4 * 1024
......
......@@ -7,7 +7,7 @@ if defined?(ActiveRecord::Base) && !Sidekiq.server?
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
Rails.logger.debug("ActiveRecord connection established")
Rails.logger.debug("ActiveRecord connection established") # rubocop:disable Gitlab/RailsLogger
end
end
end
......@@ -18,6 +18,6 @@ if defined?(ActiveRecord::Base)
# as there's no need for the master process to hold a connection
ActiveRecord::Base.connection.disconnect!
Rails.logger.debug("ActiveRecord connection disconnected")
Rails.logger.debug("ActiveRecord connection disconnected") # rubocop:disable Gitlab/RailsLogger
end
end
......@@ -2,7 +2,7 @@ if Rails.env.development? || ENV['GITLAB_LEGACY_PATH_LOG_MESSAGE']
deprecator = ActiveSupport::Deprecation.new('11.0', 'GitLab')
deprecator.behavior = -> (message, callstack) {
Rails.logger.warn("#{message}: #{callstack[1..20].join}")
Rails.logger.warn("#{message}: #{callstack[1..20].join}") # rubocop:disable Gitlab/RailsLogger
}
ActiveSupport::Deprecation.deprecate_methods(Gitlab::GitalyClient::StorageSettings, :legacy_disk_path, deprecator: deprecator)
......
......@@ -72,7 +72,7 @@ Sidekiq.configure_server do |config|
cron_jobs[k]['class'] = cron_jobs[k].delete('job_class')
else
cron_jobs.delete(k)
Rails.logger.error("Invalid cron_jobs config key: '#{k}'. Check your gitlab config file.")
Rails.logger.error("Invalid cron_jobs config key: '#{k}'. Check your gitlab config file.") # rubocop:disable Gitlab/RailsLogger
end
end
Sidekiq::Cron::Job.load_from_hash! cron_jobs
......@@ -83,7 +83,7 @@ Sidekiq.configure_server do |config|
Rails.application.config.database_configuration[Rails.env]
db_config['pool'] = Sidekiq.options[:concurrency]
ActiveRecord::Base.establish_connection(db_config)
Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}")
Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}") # rubocop:disable Gitlab/RailsLogger
Gitlab.ee do
Gitlab::Mirror.configure_cron_job!
......@@ -94,7 +94,7 @@ Sidekiq.configure_server do |config|
Rails.configuration.geo_database['pool'] = Sidekiq.options[:concurrency]
Geo::TrackingBase.establish_connection(Rails.configuration.geo_database)
Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{Geo::TrackingBase.connection_pool.size} (Geo tracking database)")
Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{Geo::TrackingBase.connection_pool.size} (Geo tracking database)") # rubocop:disable Gitlab/RailsLogger
end
end
......
post '/api/graphql', to: 'graphql#execute'
mount GraphiQL::Rails::Engine, at: '/-/graphql-explorer', graphql_path: '/api/graphql'
::API::API.logger Rails.logger
::API::API.logger Rails.logger # rubocop:disable Gitlab/RailsLogger
mount ::API::API => '/'
# frozen_string_literal: true
require Rails.root.join('db/importers/common_metrics_importer.rb')
::Importers::CommonMetricsImporter.new.execute
::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
# frozen_string_literal: true
require Rails.root.join('db/importers/common_metrics_importer.rb')
::Importers::CommonMetricsImporter.new.execute
::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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