1// Copyright 2017 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package spanner
16
17import (
18	"context"
19
20	"go.opencensus.io/stats"
21	"go.opencensus.io/stats/view"
22	"go.opencensus.io/tag"
23)
24
25const statsPrefix = "cloud.google.com/go/spanner/"
26
27var (
28	tagKeyClientID   = tag.MustNewKey("client_id")
29	tagKeyDatabase   = tag.MustNewKey("database")
30	tagKeyInstance   = tag.MustNewKey("instance_id")
31	tagKeyLibVersion = tag.MustNewKey("library_version")
32	tagKeyType       = tag.MustNewKey("type")
33	tagCommonKeys    = []tag.Key{tagKeyClientID, tagKeyDatabase, tagKeyInstance, tagKeyLibVersion}
34
35	tagNumInUseSessions = tag.Tag{Key: tagKeyType, Value: "num_in_use_sessions"}
36	tagNumBeingPrepared = tag.Tag{Key: tagKeyType, Value: "num_sessions_being_prepared"}
37	tagNumReadSessions  = tag.Tag{Key: tagKeyType, Value: "num_read_sessions"}
38	tagNumWriteSessions = tag.Tag{Key: tagKeyType, Value: "num_write_prepared_sessions"}
39)
40
41func recordStat(ctx context.Context, m *stats.Int64Measure, n int64) {
42	stats.Record(ctx, m.M(n))
43}
44
45var (
46	// OpenSessionCount is a measure of the number of sessions currently opened.
47	// It is EXPERIMENTAL and subject to change or removal without notice.
48	OpenSessionCount = stats.Int64(
49		statsPrefix+"open_session_count",
50		"Number of sessions currently opened",
51		stats.UnitDimensionless,
52	)
53
54	// OpenSessionCountView is a view of the last value of OpenSessionCount.
55	// It is EXPERIMENTAL and subject to change or removal without notice.
56	OpenSessionCountView = &view.View{
57		Measure:     OpenSessionCount,
58		Aggregation: view.LastValue(),
59		TagKeys:     tagCommonKeys,
60	}
61
62	// MaxAllowedSessionsCount is a measure of the maximum number of sessions
63	// allowed. Configurable by the user.
64	MaxAllowedSessionsCount = stats.Int64(
65		statsPrefix+"max_allowed_sessions",
66		"The maximum number of sessions allowed. Configurable by the user.",
67		stats.UnitDimensionless,
68	)
69
70	// MaxAllowedSessionsCountView is a view of the last value of
71	// MaxAllowedSessionsCount.
72	MaxAllowedSessionsCountView = &view.View{
73		Measure:     MaxAllowedSessionsCount,
74		Aggregation: view.LastValue(),
75		TagKeys:     tagCommonKeys,
76	}
77
78	// SessionsCount is a measure of the number of sessions in the pool
79	// including both in-use, idle, and being prepared.
80	SessionsCount = stats.Int64(
81		statsPrefix+"num_sessions_in_pool",
82		"The number of sessions currently in use.",
83		stats.UnitDimensionless,
84	)
85
86	// SessionsCountView is a view of the last value of SessionsCount.
87	SessionsCountView = &view.View{
88		Measure:     SessionsCount,
89		Aggregation: view.LastValue(),
90		TagKeys:     append(tagCommonKeys, tagKeyType),
91	}
92
93	// MaxInUseSessionsCount is a measure of the maximum number of sessions
94	// in use during the last 10 minute interval.
95	MaxInUseSessionsCount = stats.Int64(
96		statsPrefix+"max_in_use_sessions",
97		"The maximum number of sessions in use during the last 10 minute interval.",
98		stats.UnitDimensionless,
99	)
100
101	// MaxInUseSessionsCountView is a view of the last value of
102	// MaxInUseSessionsCount.
103	MaxInUseSessionsCountView = &view.View{
104		Measure:     MaxInUseSessionsCount,
105		Aggregation: view.LastValue(),
106		TagKeys:     tagCommonKeys,
107	}
108
109	// GetSessionTimeoutsCount is a measure of the number of get sessions
110	// timeouts due to pool exhaustion.
111	GetSessionTimeoutsCount = stats.Int64(
112		statsPrefix+"get_session_timeouts",
113		"The number of get sessions timeouts due to pool exhaustion.",
114		stats.UnitDimensionless,
115	)
116
117	// GetSessionTimeoutsCountView is a view of the last value of
118	// GetSessionTimeoutsCount.
119	GetSessionTimeoutsCountView = &view.View{
120		Measure:     GetSessionTimeoutsCount,
121		Aggregation: view.Count(),
122		TagKeys:     tagCommonKeys,
123	}
124
125	// AcquiredSessionsCount is the number of sessions acquired from
126	// the session pool.
127	AcquiredSessionsCount = stats.Int64(
128		statsPrefix+"num_acquired_sessions",
129		"The number of sessions acquired from the session pool.",
130		stats.UnitDimensionless,
131	)
132
133	// AcquiredSessionsCountView is a view of the last value of
134	// AcquiredSessionsCount.
135	AcquiredSessionsCountView = &view.View{
136		Measure:     AcquiredSessionsCount,
137		Aggregation: view.Count(),
138		TagKeys:     tagCommonKeys,
139	}
140
141	// ReleasedSessionsCount is the number of sessions released by the user
142	// and pool maintainer.
143	ReleasedSessionsCount = stats.Int64(
144		statsPrefix+"num_released_sessions",
145		"The number of sessions released by the user and pool maintainer.",
146		stats.UnitDimensionless,
147	)
148
149	// ReleasedSessionsCountView is a view of the last value of
150	// ReleasedSessionsCount.
151	ReleasedSessionsCountView = &view.View{
152		Measure:     ReleasedSessionsCount,
153		Aggregation: view.Count(),
154		TagKeys:     tagCommonKeys,
155	}
156)
157
158// EnableStatViews enables all views of metrics relate to session management.
159func EnableStatViews() error {
160	return view.Register(
161		OpenSessionCountView,
162		MaxAllowedSessionsCountView,
163		SessionsCountView,
164		MaxInUseSessionsCountView,
165		GetSessionTimeoutsCountView,
166		AcquiredSessionsCountView,
167		ReleasedSessionsCountView,
168	)
169}
170