Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
a358c7f5
Commit
a358c7f5
authored
Jun 04, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
c59205e4
327cae1d
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
378 additions
and
105 deletions
+378
-105
app/assets/javascripts/monitoring/components/dashboard.vue
app/assets/javascripts/monitoring/components/dashboard.vue
+4
-3
app/assets/javascripts/operation_settings/components/external_dashboard.vue
...ipts/operation_settings/components/external_dashboard.vue
+20
-11
app/assets/javascripts/operation_settings/index.js
app/assets/javascripts/operation_settings/index.js
+3
-6
app/assets/javascripts/operation_settings/store/actions.js
app/assets/javascripts/operation_settings/store/actions.js
+38
-0
app/assets/javascripts/operation_settings/store/index.js
app/assets/javascripts/operation_settings/store/index.js
+16
-0
app/assets/javascripts/operation_settings/store/mutation_types.js
...ts/javascripts/operation_settings/store/mutation_types.js
+3
-0
app/assets/javascripts/operation_settings/store/mutations.js
app/assets/javascripts/operation_settings/store/mutations.js
+7
-0
app/assets/javascripts/operation_settings/store/state.js
app/assets/javascripts/operation_settings/store/state.js
+5
-0
app/views/projects/settings/operations/_external_dashboard.html.haml
...rojects/settings/operations/_external_dashboard.html.haml
+2
-1
doc/administration/monitoring/prometheus/gitlab_metrics.md
doc/administration/monitoring/prometheus/gitlab_metrics.md
+11
-6
lib/gitlab/metrics/samplers/ruby_sampler.rb
lib/gitlab/metrics/samplers/ruby_sampler.rb
+23
-8
lib/gitlab/metrics/samplers/unicorn_sampler.rb
lib/gitlab/metrics/samplers/unicorn_sampler.rb
+23
-13
lib/gitlab/metrics/system.rb
lib/gitlab/metrics/system.rb
+28
-0
spec/frontend/operation_settings/components/external_dashboard_spec.js
.../operation_settings/components/external_dashboard_spec.js
+103
-47
spec/frontend/operation_settings/store/mutations_spec.js
spec/frontend/operation_settings/store/mutations_spec.js
+19
-0
spec/javascripts/monitoring/dashboard_spec.js
spec/javascripts/monitoring/dashboard_spec.js
+2
-2
spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+27
-3
spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
+20
-5
spec/lib/gitlab/metrics/system_spec.rb
spec/lib/gitlab/metrics/system_spec.rb
+24
-0
No files found.
app/assets/javascripts/monitoring/components/dashboard.vue
View file @
a358c7f5
...
@@ -38,7 +38,7 @@ export default {
...
@@ -38,7 +38,7 @@ export default {
GlModalDirective
,
GlModalDirective
,
},
},
props
:
{
props
:
{
externalDashboard
Path
:
{
externalDashboard
Url
:
{
type
:
String
,
type
:
String
,
required
:
false
,
required
:
false
,
default
:
''
,
default
:
''
,
...
@@ -299,10 +299,11 @@ export default {
...
@@ -299,10 +299,11 @@ export default {
</gl-modal>
</gl-modal>
</div>
</div>
<gl-button
<gl-button
v-if=
"externalDashboard
Path
.length"
v-if=
"externalDashboard
Url
.length"
class=
"js-external-dashboard-link prepend-left-8"
class=
"js-external-dashboard-link prepend-left-8"
variant=
"primary"
variant=
"primary"
:href=
"externalDashboardPath"
:href=
"externalDashboardUrl"
target=
"_blank"
>
>
{{
__
(
'
View full dashboard
'
)
}}
{{
__
(
'
View full dashboard
'
)
}}
<icon
name=
"external-link"
/>
<icon
name=
"external-link"
/>
...
...
app/assets/javascripts/operation_settings/components/external_dashboard.vue
View file @
a358c7f5
<
script
>
<
script
>
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
{
GlButton
,
GlFormGroup
,
GlFormInput
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
GlButton
,
GlFormGroup
,
GlFormInput
,
GlLink
}
from
'
@gitlab/ui
'
;
export
default
{
export
default
{
...
@@ -8,17 +9,24 @@ export default {
...
@@ -8,17 +9,24 @@ export default {
GlFormInput
,
GlFormInput
,
GlLink
,
GlLink
,
},
},
props
:
{
computed
:
{
externalDashboardPath
:
{
...
mapState
([
type
:
String
,
'
externalDashboardHelpPagePath
'
,
required
:
false
,
'
externalDashboardUrl
'
,
default
:
''
,
'
operationsSettingsEndpoint
'
,
]),
userDashboardUrl
:
{
get
()
{
return
this
.
externalDashboardUrl
;
},
},
externalDashboardHelpPagePath
:
{
set
(
url
)
{
type
:
String
,
this
.
setExternalDashboardUrl
(
url
);
required
:
true
,
},
},
},
},
},
methods
:
{
...
mapActions
([
'
setExternalDashboardUrl
'
,
'
updateExternalDashboardUrl
'
]),
},
};
};
</
script
>
</
script
>
...
@@ -45,11 +53,12 @@ export default {
...
@@ -45,11 +53,12 @@ export default {
:description=
"s__('ExternalMetrics|Enter the URL of the dashboard you want to link to')"
:description=
"s__('ExternalMetrics|Enter the URL of the dashboard you want to link to')"
>
>
<gl-form-input
<gl-form-input
:value=
"externalDashboardPath
"
v-model=
"userDashboardUrl
"
placeholder=
"https://my-org.gitlab.io/my-dashboards"
placeholder=
"https://my-org.gitlab.io/my-dashboards"
@
keydown.enter.native.prevent=
"updateExternalDashboardUrl"
/>
/>
</gl-form-group>
</gl-form-group>
<gl-button
variant=
"success"
>
<gl-button
variant=
"success"
@
click=
"updateExternalDashboardUrl"
>
{{
__
(
'
Save Changes
'
)
}}
{{
__
(
'
Save Changes
'
)
}}
</gl-button>
</gl-button>
</form>
</form>
...
...
app/assets/javascripts/operation_settings/index.js
View file @
a358c7f5
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
store
from
'
./store
'
;
import
ExternalDashboardForm
from
'
./components/external_dashboard.vue
'
;
import
ExternalDashboardForm
from
'
./components/external_dashboard.vue
'
;
export
default
()
=>
{
export
default
()
=>
{
...
@@ -14,13 +15,9 @@ export default () => {
...
@@ -14,13 +15,9 @@ export default () => {
return
new
Vue
({
return
new
Vue
({
el
,
el
,
store
:
store
(
el
.
dataset
),
render
(
createElement
)
{
render
(
createElement
)
{
return
createElement
(
ExternalDashboardForm
,
{
return
createElement
(
ExternalDashboardForm
);
props
:
{
...
el
.
dataset
,
expanded
:
false
,
},
});
},
},
});
});
};
};
app/assets/javascripts/operation_settings/store/actions.js
0 → 100644
View file @
a358c7f5
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
__
}
from
'
~/locale
'
;
import
createFlash
from
'
~/flash
'
;
import
{
refreshCurrentPage
}
from
'
~/lib/utils/url_utility
'
;
import
*
as
mutationTypes
from
'
./mutation_types
'
;
export
const
setExternalDashboardUrl
=
({
commit
},
url
)
=>
commit
(
mutationTypes
.
SET_EXTERNAL_DASHBOARD_URL
,
url
);
export
const
updateExternalDashboardUrl
=
({
state
,
dispatch
})
=>
axios
.
patch
(
state
.
operationsSettingsEndpoint
,
{
project
:
{
metrics_setting_attributes
:
{
external_dashboard_url
:
state
.
externalDashboardUrl
,
},
},
})
.
then
(()
=>
dispatch
(
'
receiveExternalDashboardUpdateSuccess
'
))
.
catch
(
error
=>
dispatch
(
'
receiveExternalDashboardUpdateError
'
,
error
));
export
const
receiveExternalDashboardUpdateSuccess
=
()
=>
{
/**
* The operations_controller currently handles successful requests
* by creating a flash banner messsage to notify the user.
*/
refreshCurrentPage
();
};
export
const
receiveExternalDashboardUpdateError
=
(
_
,
error
)
=>
{
const
{
response
}
=
error
;
const
message
=
response
.
data
&&
response
.
data
.
message
?
response
.
data
.
message
:
''
;
createFlash
(
`
${
__
(
'
There was an error saving your changes.
'
)}
${
message
}
`
,
'
alert
'
);
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export
default
()
=>
{};
app/assets/javascripts/operation_settings/store/index.js
0 → 100644
View file @
a358c7f5
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
createState
from
'
./state
'
;
import
*
as
actions
from
'
./actions
'
;
import
mutations
from
'
./mutations
'
;
Vue
.
use
(
Vuex
);
export
const
createStore
=
initialState
=>
new
Vuex
.
Store
({
state
:
createState
(
initialState
),
actions
,
mutations
,
});
export
default
createStore
;
app/assets/javascripts/operation_settings/store/mutation_types.js
0 → 100644
View file @
a358c7f5
/* eslint-disable import/prefer-default-export */
export
const
SET_EXTERNAL_DASHBOARD_URL
=
'
SET_EXTERNAL_DASHBOARD_URL
'
;
app/assets/javascripts/operation_settings/store/mutations.js
0 → 100644
View file @
a358c7f5
import
*
as
types
from
'
./mutation_types
'
;
export
default
{
[
types
.
SET_EXTERNAL_DASHBOARD_URL
](
state
,
url
)
{
state
.
externalDashboardUrl
=
url
;
},
};
app/assets/javascripts/operation_settings/store/state.js
0 → 100644
View file @
a358c7f5
export
default
(
initialState
=
{})
=>
({
externalDashboardUrl
:
initialState
.
externalDashboardUrl
||
''
,
operationsSettingsEndpoint
:
initialState
.
operationsSettingsEndpoint
,
externalDashboardHelpPagePath
:
initialState
.
externalDashboardHelpPagePath
,
});
app/views/projects/settings/operations/_external_dashboard.html.haml
View file @
a358c7f5
.js-operation-settings
{
data:
{
external_dashboard:
{
path:
metrics_external_dashboard_url
,
.js-operation-settings
{
data:
{
operations_settings_endpoint:
project_settings_operations_path
(
@project
),
external_dashboard:
{
url:
metrics_external_dashboard_url
,
help_page_path:
help_page_path
(
'user/project/operations/link_to_external_dashboard'
)
}
}
}
help_page_path:
help_page_path
(
'user/project/operations/link_to_external_dashboard'
)
}
}
}
doc/administration/monitoring/prometheus/gitlab_metrics.md
View file @
a358c7f5
...
@@ -47,6 +47,7 @@ The following metrics are available:
...
@@ -47,6 +47,7 @@ The following metrics are available:
| successful_login_captcha_total | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login |
| successful_login_captcha_total | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login |
| unicorn_active_connections | Gauge | 11.0 | The number of active Unicorn connections (workers) |
| unicorn_active_connections | Gauge | 11.0 | The number of active Unicorn connections (workers) |
| unicorn_queued_connections | Gauge | 11.0 | The number of queued Unicorn connections |
| unicorn_queued_connections | Gauge | 11.0 | The number of queued Unicorn connections |
| unicorn_workers | Gauge | 12.0 | The number of Unicorn workers |
## Sidekiq Metrics available for Geo **[PREMIUM]**
## Sidekiq Metrics available for Geo **[PREMIUM]**
...
@@ -100,6 +101,10 @@ Some basic Ruby runtime metrics are available:
...
@@ -100,6 +101,10 @@ Some basic Ruby runtime metrics are available:
| ruby_file_descriptors | Gauge | 11.1 | File descriptors per process |
| ruby_file_descriptors | Gauge | 11.1 | File descriptors per process |
| ruby_memory_bytes | Gauge | 11.1 | Memory usage by process |
| ruby_memory_bytes | Gauge | 11.1 | Memory usage by process |
| ruby_sampler_duration_seconds_total | Counter | 11.1 | Time spent collecting stats |
| ruby_sampler_duration_seconds_total | Counter | 11.1 | Time spent collecting stats |
| ruby_process_cpu_seconds_total | Gauge | 12.0 | Total amount of CPU time per process |
| ruby_process_max_fds | Gauge | 12.0 | Maximum number of open file descriptors per process |
| ruby_process_resident_memory_bytes | Gauge | 12.0 | Memory usage by process, measured in bytes |
| ruby_process_start_time_seconds | Gauge | 12.0 | The elapsed time between system boot and the process started, measured in seconds |
[
GC.stat
]:
https://ruby-doc.org/core-2.3.0/GC.html#method-c-stat
[
GC.stat
]:
https://ruby-doc.org/core-2.3.0/GC.html#method-c-stat
...
...
lib/gitlab/metrics/samplers/ruby_sampler.rb
View file @
a358c7f5
...
@@ -23,25 +23,32 @@ module Gitlab
...
@@ -23,25 +23,32 @@ module Gitlab
end
end
def
init_metrics
def
init_metrics
metrics
=
{}
metrics
=
{
metrics
[
:sampler_duration
]
=
::
Gitlab
::
Metrics
.
counter
(
with_prefix
(
:sampler
,
:duration_seconds_total
),
'Sampler time'
,
labels
)
file_descriptors:
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:file
,
:descriptors
),
'File descriptors used'
,
labels
,
:livesum
),
metrics
[
:total_time
]
=
::
Gitlab
::
Metrics
.
counter
(
with_prefix
(
:gc
,
:duration_seconds_total
),
'Total GC time'
,
labels
)
memory_bytes:
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:memory
,
:bytes
),
'Memory used'
,
labels
,
:livesum
),
process_cpu_seconds_total:
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:process
,
:cpu_seconds_total
),
'Process CPU seconds total'
),
process_max_fds:
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:process
,
:max_fds
),
'Process max fds'
),
process_resident_memory_bytes:
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:process
,
:resident_memory_bytes
),
'Memory used'
,
labels
,
:livesum
),
process_start_time_seconds:
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:process
,
:start_time_seconds
),
'Process start time seconds'
),
sampler_duration:
::
Gitlab
::
Metrics
.
counter
(
with_prefix
(
:sampler
,
:duration_seconds_total
),
'Sampler time'
,
labels
),
total_time:
::
Gitlab
::
Metrics
.
counter
(
with_prefix
(
:gc
,
:duration_seconds_total
),
'Total GC time'
,
labels
)
}
GC
.
stat
.
keys
.
each
do
|
key
|
GC
.
stat
.
keys
.
each
do
|
key
|
metrics
[
key
]
=
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:gc_stat
,
key
),
to_doc_string
(
key
),
labels
,
:livesum
)
metrics
[
key
]
=
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:gc_stat
,
key
),
to_doc_string
(
key
),
labels
,
:livesum
)
end
end
metrics
[
:memory_usage
]
=
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:memory
,
:bytes
),
'Memory used'
,
labels
,
:livesum
)
metrics
[
:file_descriptors
]
=
::
Gitlab
::
Metrics
.
gauge
(
with_prefix
(
:file
,
:descriptors
),
'File descriptors used'
,
labels
,
:livesum
)
metrics
metrics
end
end
def
sample
def
sample
start_time
=
System
.
monotonic_time
start_time
=
System
.
monotonic_time
metrics
[
:memory_usage
].
set
(
labels
.
merge
(
worker_label
),
System
.
memory_usage
)
metrics
[
:file_descriptors
].
set
(
labels
.
merge
(
worker_label
),
System
.
file_descriptor_count
)
metrics
[
:file_descriptors
].
set
(
labels
.
merge
(
worker_label
),
System
.
file_descriptor_count
)
metrics
[
:process_cpu_seconds_total
].
set
(
labels
.
merge
(
worker_label
),
::
Gitlab
::
Metrics
::
System
.
cpu_time
)
metrics
[
:process_max_fds
].
set
(
labels
.
merge
(
worker_label
),
::
Gitlab
::
Metrics
::
System
.
max_open_file_descriptors
)
metrics
[
:process_start_time_seconds
].
set
(
labels
.
merge
(
worker_label
),
::
Gitlab
::
Metrics
::
System
.
process_start_time
)
set_memory_usage_metrics
sample_gc
sample_gc
metrics
[
:sampler_duration
].
increment
(
labels
,
System
.
monotonic_time
-
start_time
)
metrics
[
:sampler_duration
].
increment
(
labels
,
System
.
monotonic_time
-
start_time
)
...
@@ -61,6 +68,14 @@ module Gitlab
...
@@ -61,6 +68,14 @@ module Gitlab
metrics
[
:total_time
].
increment
(
labels
,
GC
::
Profiler
.
total_time
)
metrics
[
:total_time
].
increment
(
labels
,
GC
::
Profiler
.
total_time
)
end
end
def
set_memory_usage_metrics
memory_usage
=
System
.
memory_usage
memory_labels
=
labels
.
merge
(
worker_label
)
metrics
[
:memory_bytes
].
set
(
memory_labels
,
memory_usage
)
metrics
[
:process_resident_memory_bytes
].
set
(
memory_labels
,
memory_usage
)
end
def
worker_label
def
worker_label
return
{}
unless
defined?
(
Unicorn
::
Worker
)
return
{}
unless
defined?
(
Unicorn
::
Worker
)
...
...
lib/gitlab/metrics/samplers/unicorn_sampler.rb
View file @
a358c7f5
...
@@ -4,16 +4,16 @@ module Gitlab
...
@@ -4,16 +4,16 @@ module Gitlab
module
Metrics
module
Metrics
module
Samplers
module
Samplers
class
UnicornSampler
<
BaseSampler
class
UnicornSampler
<
BaseSampler
def
initialize
(
interval
)
def
metrics
super
(
interval
)
@metrics
||=
init_metrics
end
end
def
unicorn_active_connection
s
def
init_metric
s
@unicorn_active_connections
||=
::
Gitlab
::
Metrics
.
gauge
(
:unicorn_active_connections
,
'Unicorn active connections'
,
{},
:max
)
{
end
unicorn_active_connections:
::
Gitlab
::
Metrics
.
gauge
(
:unicorn_active_connections
,
'Unicorn active connections'
,
{},
:max
),
unicorn_queued_connections:
::
Gitlab
::
Metrics
.
gauge
(
:unicorn_queued_connections
,
'Unicorn queued connections'
,
{},
:max
),
def
unicorn_queued_connections
unicorn_workers:
::
Gitlab
::
Metrics
.
gauge
(
:unicorn_workers
,
'Unicorn workers'
)
@unicorn_queued_connections
||=
::
Gitlab
::
Metrics
.
gauge
(
:unicorn_queued_connections
,
'Unicorn queued connections'
,
{},
:max
)
}
end
end
def
enabled?
def
enabled?
...
@@ -23,14 +23,13 @@ module Gitlab
...
@@ -23,14 +23,13 @@ module Gitlab
def
sample
def
sample
Raindrops
::
Linux
.
tcp_listener_stats
(
tcp_listeners
).
each
do
|
addr
,
stats
|
Raindrops
::
Linux
.
tcp_listener_stats
(
tcp_listeners
).
each
do
|
addr
,
stats
|
unicorn_active_connections
.
set
({
socket_type:
'tcp'
,
socket_address:
addr
},
stats
.
active
)
set_unicorn_connection_metrics
(
'tcp'
,
addr
,
stats
)
unicorn_queued_connections
.
set
({
socket_type:
'tcp'
,
socket_address:
addr
},
stats
.
queued
)
end
end
Raindrops
::
Linux
.
unix_listener_stats
(
unix_listeners
).
each
do
|
addr
,
stats
|
Raindrops
::
Linux
.
unix_listener_stats
(
unix_listeners
).
each
do
|
addr
,
stats
|
unicorn_active_connections
.
set
({
socket_type:
'unix'
,
socket_address:
addr
},
stats
.
active
)
set_unicorn_connection_metrics
(
'unix'
,
addr
,
stats
)
unicorn_queued_connections
.
set
({
socket_type:
'unix'
,
socket_address:
addr
},
stats
.
queued
)
end
end
metrics
[
:unicorn_workers
].
set
({},
unicorn_workers_count
)
end
end
private
private
...
@@ -39,6 +38,13 @@ module Gitlab
...
@@ -39,6 +38,13 @@ module Gitlab
@tcp_listeners
||=
Unicorn
.
listener_names
.
grep
(
%r{
\A
[^/]+:
\d
+
\z
}
)
@tcp_listeners
||=
Unicorn
.
listener_names
.
grep
(
%r{
\A
[^/]+:
\d
+
\z
}
)
end
end
def
set_unicorn_connection_metrics
(
type
,
addr
,
stats
)
labels
=
{
socket_type:
type
,
socket_address:
addr
}
metrics
[
:unicorn_active_connections
].
set
(
labels
,
stats
.
active
)
metrics
[
:unicorn_queued_connections
].
set
(
labels
,
stats
.
queued
)
end
def
unix_listeners
def
unix_listeners
@unix_listeners
||=
Unicorn
.
listener_names
-
tcp_listeners
@unix_listeners
||=
Unicorn
.
listener_names
-
tcp_listeners
end
end
...
@@ -46,6 +52,10 @@ module Gitlab
...
@@ -46,6 +52,10 @@ module Gitlab
def
unicorn_with_listeners?
def
unicorn_with_listeners?
defined?
(
Unicorn
)
&&
Unicorn
.
listener_names
.
any?
defined?
(
Unicorn
)
&&
Unicorn
.
listener_names
.
any?
end
end
def
unicorn_workers_count
`pgrep -f '[u]nicorn_rails worker.+
#{
Rails
.
root
.
to_s
}
'`
.
split
.
count
end
end
end
end
end
end
end
...
...
lib/gitlab/metrics/system.rb
View file @
a358c7f5
...
@@ -23,6 +23,22 @@ module Gitlab
...
@@ -23,6 +23,22 @@ module Gitlab
def
self
.
file_descriptor_count
def
self
.
file_descriptor_count
Dir
.
glob
(
'/proc/self/fd/*'
).
length
Dir
.
glob
(
'/proc/self/fd/*'
).
length
end
end
def
self
.
max_open_file_descriptors
match
=
File
.
read
(
'/proc/self/limits'
).
match
(
/Max open files\s*(\d+)/
)
return
unless
match
&&
match
[
1
]
match
[
1
].
to_i
end
def
self
.
process_start_time
fields
=
File
.
read
(
'/proc/self/stat'
).
split
# fields[21] is linux proc stat field "(22) starttime".
# The value is expressed in clock ticks, divide by clock ticks for seconds.
(
fields
[
21
].
to_i
||
0
)
/
clk_tck
end
else
else
def
self
.
memory_usage
def
self
.
memory_usage
0.0
0.0
...
@@ -31,6 +47,14 @@ module Gitlab
...
@@ -31,6 +47,14 @@ module Gitlab
def
self
.
file_descriptor_count
def
self
.
file_descriptor_count
0
0
end
end
def
self
.
max_open_file_descriptors
0
end
def
self
.
process_start_time
0
end
end
end
# THREAD_CPUTIME is not supported on OS X
# THREAD_CPUTIME is not supported on OS X
...
@@ -59,6 +83,10 @@ module Gitlab
...
@@ -59,6 +83,10 @@ module Gitlab
def
self
.
monotonic_time
def
self
.
monotonic_time
Process
.
clock_gettime
(
Process
::
CLOCK_MONOTONIC
,
:float_second
)
Process
.
clock_gettime
(
Process
::
CLOCK_MONOTONIC
,
:float_second
)
end
end
def
self
.
clk_tck
@clk_tck
||=
`getconf CLK_TCK`
.
to_i
end
end
end
end
end
end
end
spec/frontend/operation_settings/components/external_dashboard_spec.js
View file @
a358c7f5
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
mount
,
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
GlButton
,
GlLink
,
GlFormGroup
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
GlButton
,
GlLink
,
GlFormGroup
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
ExternalDashboard
from
'
~/operation_settings/components/external_dashboard.vue
'
;
import
ExternalDashboard
from
'
~/operation_settings/components/external_dashboard.vue
'
;
import
store
from
'
~/operation_settings/store
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
refreshCurrentPage
}
from
'
~/lib/utils/url_utility
'
;
import
createFlash
from
'
~/flash
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
jest
.
mock
(
'
~/lib/utils/axios_utils
'
);
jest
.
mock
(
'
~/lib/utils/url_utility
'
);
jest
.
mock
(
'
~/flash
'
);
describe
(
'
operation settings external dashboard component
'
,
()
=>
{
describe
(
'
operation settings external dashboard component
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
const
externalDashboardPath
=
`http://mock-external-domain.com/external/dashboard/path`
;
const
operationsSettingsEndpoint
=
`
${
TEST_HOST
}
/mock/ops/settings/endpoint`
;
const
externalDashboardUrl
=
`http://mock-external-domain.com/external/dashboard/url`
;
const
externalDashboardHelpPagePath
=
`
${
TEST_HOST
}
/help/page/path`
;
const
externalDashboardHelpPagePath
=
`
${
TEST_HOST
}
/help/page/path`
;
const
localVue
=
createLocalVue
();
beforeEach
(()
=>
{
const
mountComponent
=
(
shallow
=
true
)
=>
{
wrapper
=
shallowMount
(
ExternalDashboard
,
{
const
config
=
[
propsData
:
{
ExternalDashboard
,
externalDashboardPath
,
{
localVue
,
store
:
store
({
operationsSettingsEndpoint
,
externalDashboardUrl
,
externalDashboardHelpPagePath
,
externalDashboardHelpPagePath
,
}),
},
},
});
];
wrapper
=
shallow
?
shallowMount
(...
config
)
:
mount
(...
config
);
};
afterEach
(()
=>
{
if
(
wrapper
.
destroy
)
{
wrapper
.
destroy
();
}
axios
.
patch
.
mockReset
();
refreshCurrentPage
.
mockReset
();
createFlash
.
mockReset
();
});
});
it
(
'
renders header text
'
,
()
=>
{
it
(
'
renders header text
'
,
()
=>
{
mountComponent
();
expect
(
wrapper
.
find
(
'
.js-section-header
'
).
text
()).
toBe
(
'
External Dashboard
'
);
expect
(
wrapper
.
find
(
'
.js-section-header
'
).
text
()).
toBe
(
'
External Dashboard
'
);
});
});
...
@@ -33,6 +58,7 @@ describe('operation settings external dashboard component', () => {
...
@@ -33,6 +58,7 @@ describe('operation settings external dashboard component', () => {
let
subHeader
;
let
subHeader
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
mountComponent
();
subHeader
=
wrapper
.
find
(
'
.js-section-sub-header
'
);
subHeader
=
wrapper
.
find
(
'
.js-section-sub-header
'
);
});
});
...
@@ -51,18 +77,12 @@ describe('operation settings external dashboard component', () => {
...
@@ -51,18 +77,12 @@ describe('operation settings external dashboard component', () => {
});
});
describe
(
'
form
'
,
()
=>
{
describe
(
'
form
'
,
()
=>
{
let
form
;
beforeEach
(()
=>
{
form
=
wrapper
.
find
(
'
form
'
);
});
describe
(
'
external dashboard url
'
,
()
=>
{
describe
(
'
input label
'
,
()
=>
{
describe
(
'
input label
'
,
()
=>
{
let
formGroup
;
let
formGroup
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
formGroup
=
form
.
find
(
GlFormGroup
);
mountComponent
();
formGroup
=
wrapper
.
find
(
GlFormGroup
);
});
});
it
(
'
uses label text
'
,
()
=>
{
it
(
'
uses label text
'
,
()
=>
{
...
@@ -80,11 +100,12 @@ describe('operation settings external dashboard component', () => {
...
@@ -80,11 +100,12 @@ describe('operation settings external dashboard component', () => {
let
input
;
let
input
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
input
=
form
.
find
(
GlFormInput
);
mountComponent
();
input
=
wrapper
.
find
(
GlFormInput
);
});
});
it
(
'
defaults to externalDashboardPath prop
'
,
()
=>
{
it
(
'
defaults to externalDashboardUrl
'
,
()
=>
{
expect
(
input
.
attributes
().
value
).
toBe
(
externalDashboardPath
);
expect
(
input
.
attributes
().
value
).
toBe
(
externalDashboardUrl
);
});
});
it
(
'
uses a placeholder
'
,
()
=>
{
it
(
'
uses a placeholder
'
,
()
=>
{
...
@@ -93,15 +114,50 @@ describe('operation settings external dashboard component', () => {
...
@@ -93,15 +114,50 @@ describe('operation settings external dashboard component', () => {
});
});
describe
(
'
submit button
'
,
()
=>
{
describe
(
'
submit button
'
,
()
=>
{
let
submit
;
const
endpointRequest
=
[
operationsSettingsEndpoint
,
beforeEach
(()
=>
{
{
submit
=
form
.
find
(
GlButton
);
project
:
{
});
metrics_setting_attributes
:
{
external_dashboard_url
:
externalDashboardUrl
,
},
},
},
];
it
(
'
renders button label
'
,
()
=>
{
it
(
'
renders button label
'
,
()
=>
{
mountComponent
();
const
submit
=
wrapper
.
find
(
GlButton
);
expect
(
submit
.
text
()).
toBe
(
'
Save Changes
'
);
expect
(
submit
.
text
()).
toBe
(
'
Save Changes
'
);
});
});
it
(
'
submits form on click
'
,
()
=>
{
mountComponent
(
false
);
axios
.
patch
.
mockResolvedValue
();
wrapper
.
find
(
GlButton
).
trigger
(
'
click
'
);
expect
(
axios
.
patch
).
toHaveBeenCalledWith
(...
endpointRequest
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
expect
(
refreshCurrentPage
).
toHaveBeenCalled
());
});
it
(
'
creates flash banner on error
'
,
()
=>
{
mountComponent
(
false
);
const
message
=
'
mockErrorMessage
'
;
axios
.
patch
.
mockRejectedValue
({
response
:
{
data
:
{
message
}
}
});
wrapper
.
find
(
GlButton
).
trigger
(
'
click
'
);
expect
(
axios
.
patch
).
toHaveBeenCalledWith
(...
endpointRequest
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(
jest
.
runAllTicks
)
.
then
(()
=>
expect
(
createFlash
).
toHaveBeenCalledWith
(
`There was an error saving your changes.
${
message
}
`
,
'
alert
'
,
),
);
});
});
});
});
});
});
...
...
spec/frontend/operation_settings/store/mutations_spec.js
0 → 100644
View file @
a358c7f5
import
mutations
from
'
~/operation_settings/store/mutations
'
;
import
createState
from
'
~/operation_settings/store/state
'
;
describe
(
'
operation settings mutations
'
,
()
=>
{
let
localState
;
beforeEach
(()
=>
{
localState
=
createState
();
});
describe
(
'
SET_EXTERNAL_DASHBOARD_URL
'
,
()
=>
{
it
(
'
sets externalDashboardUrl
'
,
()
=>
{
const
mockUrl
=
'
mockUrl
'
;
mutations
.
SET_EXTERNAL_DASHBOARD_URL
(
localState
,
mockUrl
);
expect
(
localState
.
externalDashboardUrl
).
toBe
(
mockUrl
);
});
});
});
spec/javascripts/monitoring/dashboard_spec.js
View file @
a358c7f5
...
@@ -393,7 +393,7 @@ describe('Dashboard', () => {
...
@@ -393,7 +393,7 @@ describe('Dashboard', () => {
hasMetrics
:
true
,
hasMetrics
:
true
,
showPanels
:
false
,
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
showTimeWindowDropdown
:
false
,
externalDashboard
Path
:
'
/mockPath
'
,
externalDashboard
Url
:
'
/mockUrl
'
,
},
},
store
,
store
,
});
});
...
@@ -419,7 +419,7 @@ describe('Dashboard', () => {
...
@@ -419,7 +419,7 @@ describe('Dashboard', () => {
hasMetrics
:
true
,
hasMetrics
:
true
,
showPanels
:
false
,
showPanels
:
false
,
showTimeWindowDropdown
:
false
,
showTimeWindowDropdown
:
false
,
externalDashboard
Path
:
''
,
externalDashboard
Url
:
''
,
},
},
store
,
store
,
});
});
...
...
spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
View file @
a358c7f5
...
@@ -10,17 +10,20 @@ describe Gitlab::Metrics::Samplers::RubySampler do
...
@@ -10,17 +10,20 @@ describe Gitlab::Metrics::Samplers::RubySampler do
describe
'#sample'
do
describe
'#sample'
do
it
'samples various statistics'
do
it
'samples various statistics'
do
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:
memory_usag
e
)
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:
cpu_tim
e
)
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:file_descriptor_count
)
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:file_descriptor_count
)
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:memory_usage
)
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:process_start_time
)
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:max_open_file_descriptors
)
expect
(
sampler
).
to
receive
(
:sample_gc
)
expect
(
sampler
).
to
receive
(
:sample_gc
)
sampler
.
sample
sampler
.
sample
end
end
it
'adds a metric containing the
memory usage
'
do
it
'adds a metric containing the
process resident memory bytes
'
do
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:memory_usage
).
and_return
(
9000
)
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:memory_usage
).
and_return
(
9000
)
expect
(
sampler
.
metrics
[
:
memory_usage
]).
to
receive
(
:set
).
with
({},
9000
)
expect
(
sampler
.
metrics
[
:
process_resident_memory_bytes
]).
to
receive
(
:set
).
with
({},
9000
)
sampler
.
sample
sampler
.
sample
end
end
...
@@ -34,6 +37,27 @@ describe Gitlab::Metrics::Samplers::RubySampler do
...
@@ -34,6 +37,27 @@ describe Gitlab::Metrics::Samplers::RubySampler do
sampler
.
sample
sampler
.
sample
end
end
it
'adds a metric containing the process total cpu time'
do
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:cpu_time
).
and_return
(
0.51
)
expect
(
sampler
.
metrics
[
:process_cpu_seconds_total
]).
to
receive
(
:set
).
with
({},
0.51
)
sampler
.
sample
end
it
'adds a metric containing the process start time'
do
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:process_start_time
).
and_return
(
12345
)
expect
(
sampler
.
metrics
[
:process_start_time_seconds
]).
to
receive
(
:set
).
with
({},
12345
)
sampler
.
sample
end
it
'adds a metric containing the process max file descriptors'
do
expect
(
Gitlab
::
Metrics
::
System
).
to
receive
(
:max_open_file_descriptors
).
and_return
(
1024
)
expect
(
sampler
.
metrics
[
:process_max_fds
]).
to
receive
(
:set
).
with
({},
1024
)
sampler
.
sample
end
it
'clears any GC profiles'
do
it
'clears any GC profiles'
do
expect
(
GC
::
Profiler
).
to
receive
(
:clear
)
expect
(
GC
::
Profiler
).
to
receive
(
:clear
)
...
...
spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
View file @
a358c7f5
...
@@ -39,8 +39,8 @@ describe Gitlab::Metrics::Samplers::UnicornSampler do
...
@@ -39,8 +39,8 @@ describe Gitlab::Metrics::Samplers::UnicornSampler do
it
'updates metrics type unix and with addr'
do
it
'updates metrics type unix and with addr'
do
labels
=
{
socket_type:
'unix'
,
socket_address:
socket_address
}
labels
=
{
socket_type:
'unix'
,
socket_address:
socket_address
}
expect
(
subject
).
to
receive_message_chain
(
:unicorn_active_connections
,
:set
).
with
(
labels
,
'active'
)
expect
(
subject
.
metrics
[
:unicorn_active_connections
]).
to
receive
(
:set
).
with
(
labels
,
'active'
)
expect
(
subject
).
to
receive_message_chain
(
:unicorn_queued_connections
,
:set
).
with
(
labels
,
'queued'
)
expect
(
subject
.
metrics
[
:unicorn_queued_connections
]).
to
receive
(
:set
).
with
(
labels
,
'queued'
)
subject
.
sample
subject
.
sample
end
end
...
@@ -50,7 +50,6 @@ describe Gitlab::Metrics::Samplers::UnicornSampler do
...
@@ -50,7 +50,6 @@ describe Gitlab::Metrics::Samplers::UnicornSampler do
context
'unicorn listens on tcp sockets'
do
context
'unicorn listens on tcp sockets'
do
let
(
:tcp_socket_address
)
{
'0.0.0.0:8080'
}
let
(
:tcp_socket_address
)
{
'0.0.0.0:8080'
}
let
(
:tcp_sockets
)
{
[
tcp_socket_address
]
}
let
(
:tcp_sockets
)
{
[
tcp_socket_address
]
}
before
do
before
do
allow
(
unicorn
).
to
receive
(
:listener_names
).
and_return
(
tcp_sockets
)
allow
(
unicorn
).
to
receive
(
:listener_names
).
and_return
(
tcp_sockets
)
end
end
...
@@ -71,13 +70,29 @@ describe Gitlab::Metrics::Samplers::UnicornSampler do
...
@@ -71,13 +70,29 @@ describe Gitlab::Metrics::Samplers::UnicornSampler do
it
'updates metrics type unix and with addr'
do
it
'updates metrics type unix and with addr'
do
labels
=
{
socket_type:
'tcp'
,
socket_address:
tcp_socket_address
}
labels
=
{
socket_type:
'tcp'
,
socket_address:
tcp_socket_address
}
expect
(
subject
).
to
receive_message_chain
(
:unicorn_active_connections
,
:set
).
with
(
labels
,
'active'
)
expect
(
subject
.
metrics
[
:unicorn_active_connections
]).
to
receive
(
:set
).
with
(
labels
,
'active'
)
expect
(
subject
).
to
receive_message_chain
(
:unicorn_queued_connections
,
:set
).
with
(
labels
,
'queued'
)
expect
(
subject
.
metrics
[
:unicorn_queued_connections
]).
to
receive
(
:set
).
with
(
labels
,
'queued'
)
subject
.
sample
subject
.
sample
end
end
end
end
end
end
context
'additional metrics'
do
let
(
:unicorn_workers
)
{
2
}
before
do
allow
(
unicorn
).
to
receive
(
:listener_names
).
and_return
([
""
])
allow
(
::
Gitlab
::
Metrics
::
System
).
to
receive
(
:cpu_time
).
and_return
(
3.14
)
allow
(
subject
).
to
receive
(
:unicorn_workers_count
).
and_return
(
unicorn_workers
)
end
it
"sets additional metrics"
do
expect
(
subject
.
metrics
[
:unicorn_workers
]).
to
receive
(
:set
).
with
({},
unicorn_workers
)
subject
.
sample
end
end
end
end
describe
'#start'
do
describe
'#start'
do
...
...
spec/lib/gitlab/metrics/system_spec.rb
View file @
a358c7f5
...
@@ -13,6 +13,18 @@ describe Gitlab::Metrics::System do
...
@@ -13,6 +13,18 @@ describe Gitlab::Metrics::System do
expect
(
described_class
.
file_descriptor_count
).
to
be
>
0
expect
(
described_class
.
file_descriptor_count
).
to
be
>
0
end
end
end
end
describe
'.max_open_file_descriptors'
do
it
'returns the max allowed open file descriptors'
do
expect
(
described_class
.
max_open_file_descriptors
).
to
be
>
0
end
end
describe
'.process_start_time'
do
it
'returns the process start time'
do
expect
(
described_class
.
process_start_time
).
to
be
>
0
end
end
else
else
describe
'.memory_usage'
do
describe
'.memory_usage'
do
it
'returns 0.0'
do
it
'returns 0.0'
do
...
@@ -25,6 +37,18 @@ describe Gitlab::Metrics::System do
...
@@ -25,6 +37,18 @@ describe Gitlab::Metrics::System do
expect
(
described_class
.
file_descriptor_count
).
to
eq
(
0
)
expect
(
described_class
.
file_descriptor_count
).
to
eq
(
0
)
end
end
end
end
describe
'.max_open_file_descriptors'
do
it
'returns 0'
do
expect
(
described_class
.
max_open_file_descriptors
).
to
eq
(
0
)
end
end
describe
'process_start_time'
do
it
'returns 0'
do
expect
(
described_class
.
process_start_time
).
to
eq
(
0
)
end
end
end
end
describe
'.cpu_time'
do
describe
'.cpu_time'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment