Skip to content

Use counter for tracking container states#29554

Merged
cpuguy83 merged 1 commit into
moby:masterfrom
cpuguy83:keep_running_count_of_states
May 5, 2017
Merged

Use counter for tracking container states#29554
cpuguy83 merged 1 commit into
moby:masterfrom
cpuguy83:keep_running_count_of_states

Conversation

@cpuguy83

Copy link
Copy Markdown
Member

Container state counts are used for reporting in the /info endpoint.
Currently when /info is called, each container is iterated over and
the containers 'StateString()' is called. This is not very efficient
with lots of containers, and is also racey since StateString() is not
using a mutex and the mutex is not otherwise locked.

We could just lock the container mutex, but this is proven to be
problematic since there are frequent deadlock scenarios and we should
always have the /info endpoint available since this endpoint is used
to get general information about the docker host.

Closes #28912

@dnephin dnephin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally design SGTM, but I do have a question about it

Comment thread container/state.go Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could do something like:

defer s.UpdateCounter()()
func (s *State) UpdateCounter() func() {
    oldState := s.StateString()
    return func() {
        s.counter.SetCount(oldState, s.StateString())
    }
}

Comment thread container/state.go Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this still racy if the container changes state between oldState := s.StateString() and the defer running?

It would reduce the count of the old state twice?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right the SetCount needs to be done while the lock is held.

@cpuguy83
cpuguy83 force-pushed the keep_running_count_of_states branch 2 times, most recently from aff5310 to 31c805d Compare December 19, 2016 21:49
@AkihiroSuda AkihiroSuda added the status/failing-ci Indicates that the PR in its current state fails the test suite label Dec 20, 2016
@cpuguy83
cpuguy83 force-pushed the keep_running_count_of_states branch 2 times, most recently from 6ed6402 to 4678a2d Compare December 22, 2016 21:11
@stevvooe

Copy link
Copy Markdown
Contributor

@cpuguy83 Is there any way we could leverage the prometheus metrics registry to aggregate this data?

@AkihiroSuda

Copy link
Copy Markdown
Member

The lock-free proposal (#30225) can close this PR?

@cpuguy83

Copy link
Copy Markdown
Member Author

@AkihiroSuda I don't think so. Even with a lock-free container, it's still horrible to iterate every single container for docker info

@stevvooe

Copy link
Copy Markdown
Contributor

@AkihiroSuda I agree with @cpuguy83 here. Aggregating the entire dataset will be much less reliable than pre-aggregating with counters.

@cpuguy83 Any luck getting go-metrics to do this? Let me know if you need pointers there.

@LK4D4

LK4D4 commented Jan 30, 2017

Copy link
Copy Markdown
Contributor

@cpuguy83 CI fails :/

@cpuguy83
cpuguy83 force-pushed the keep_running_count_of_states branch 2 times, most recently from 3877dee to e25bc83 Compare February 10, 2017 03:12
@cpuguy83

Copy link
Copy Markdown
Member Author

@stevvooe I have wired in go-metrics here, although I did have to keep a separate counter for reporting to info as there doesn't really seem to be a way to query these metrics in a desirable way.

This still has some issue somewhere that so far I've only seen pop in tests where the counts get way off that I need to figure out.

@stevvooe

Copy link
Copy Markdown
Contributor

as there doesn't really seem to be a way to query these metrics in a desirable way.

@cpuguy83 That is a wise decision!

@crosbymichael @juliusv Any ideas here?

@stevvooe stevvooe closed this Feb 14, 2017
@stevvooe stevvooe reopened this Feb 14, 2017
@juliusv

juliusv commented Feb 14, 2017

Copy link
Copy Markdown

Any ideas here?

There's indeed no way to get the value of a single metric with Prometheus's Go client library, except for calling Write on it to dump it to its protobuf representation.

If you're going to maintain the count yourself anyways, you may want to think about not tracking the state twice, but using throw-away ConstMetrics every time you are scraped that just proxy your internal state to Prometheus. This is the common pattern for exporters which just translate existing values to Prometheus metrics. See for example https://github.com/prometheus/memcached_exporter/blob/master/main.go#L334.

@vdemeester

Copy link
Copy Markdown
Member

ping @cpuguy83, what is the status here ? 👼

@cpuguy83
cpuguy83 force-pushed the keep_running_count_of_states branch from e25bc83 to 9b1a79e Compare March 8, 2017 21:46
@cpuguy83

cpuguy83 commented Mar 8, 2017

Copy link
Copy Markdown
Member Author

Working on it.

@cpuguy83
cpuguy83 force-pushed the keep_running_count_of_states branch 3 times, most recently from 60b6e01 to fd78c07 Compare March 9, 2017 03:22
@cpuguy83

Copy link
Copy Markdown
Member Author

This is all green folks.

@cpuguy83 cpuguy83 removed status/failing-ci Indicates that the PR in its current state fails the test suite rebuild/powerpc labels Apr 30, 2017
@cpuguy83

cpuguy83 commented May 1, 2017

Copy link
Copy Markdown
Member Author

Something to consider b/c once metrics are out of experimental we probably ought not change this...

docker info looks at running, paused, and stopped. Where if it's not running or paused it's considered stopped (vs created, exited, etc).
Should we break these values down better for metrics?

@dnephin dnephin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

What fixed the counter problems? Was it changing the counters to be per-container containers?

@cpuguy83

cpuguy83 commented May 1, 2017

Copy link
Copy Markdown
Member Author

What fixed the counter problems?

Just started stashing the actual container state when it gets updated rather than calling inc+dec on split states.
Then we build the summary when info or the metrics endpoint is called.

@stevvooe

stevvooe commented May 1, 2017

Copy link
Copy Markdown
Contributor

LGTM after providing example /metrics output (in a gist or something).

@crosbymichael PTAL

@cpuguy83

cpuguy83 commented May 1, 2017

Copy link
Copy Markdown
Member Author

@stevvooe

stevvooe commented May 1, 2017

Copy link
Copy Markdown
Contributor

@cpuguy83 Wondering if we should make an effort to drop the engine_daemon_ prefixes... these seem redundant.

@crosbymichael

Copy link
Copy Markdown
Contributor

LGTM

Its the best we can do without the ability to query prom metrics in process. , @cpuguy83 not saying your implementation is bad, just working with what we have :) It would be a lot less code if we could query the metric in process and get the values.

@cpuguy83

cpuguy83 commented May 1, 2017

Copy link
Copy Markdown
Member Author

It would be a lot less code if we could query the metric in process and get the values

Can you explain what you mean by this?

@crosbymichael

Copy link
Copy Markdown
Contributor

If we didn't have to query for the info endpoint, you just have a single metric with labels, and you inc/dec the id+state for each of the states, its like 10 lines of code.

@cpuguy83

cpuguy83 commented May 1, 2017

Copy link
Copy Markdown
Member Author

@stevvooe Yeah, we could probably simplify the metrics namespace.
Maybe just docker_engine_* or just docker_*

@stevvooe

stevvooe commented May 1, 2017

Copy link
Copy Markdown
Contributor

@cpuguy83 Right now, it is engine_daemon_, which is a bit redundant. I am unsure about putting docker_ there, as well, since this is moby.

@cpuguy83

cpuguy83 commented May 2, 2017

Copy link
Copy Markdown
Member Author

@stevvooe Do you have a suggestion? Just remove all-together?

@stevvooe

stevvooe commented May 2, 2017

Copy link
Copy Markdown
Contributor

@stevvooe Do you have a suggestion? Just remove all-together?

I think we can remove the prefix, but I'd like to hear @crosbymichael's opinion. We put work into "namespacing" metrics but prometheus already has a lot of context, like "job", "target" and info structs that can be used to create that context.

@rogaha

rogaha commented May 3, 2017

Copy link
Copy Markdown
Contributor

LGTM

@cpuguy83

cpuguy83 commented May 4, 2017

Copy link
Copy Markdown
Member Author

@stevvooe Are you ok if we merge this and talk about namespace separately?

@cpuguy83 cpuguy83 added this to the 17.06.0 milestone May 4, 2017
@stevvooe

stevvooe commented May 5, 2017

Copy link
Copy Markdown
Contributor

LGTM

Let's open a bug to review the namespacing for metrics.

@cpuguy83 cpuguy83 mentioned this pull request May 5, 2017
@cpuguy83

cpuguy83 commented May 5, 2017

Copy link
Copy Markdown
Member Author

Opened #33056 to discuss.

Merging this one since it has all the required LGTM's and is all green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants