You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

243 lines
7.2 KiB

//
// DISCLAIMER
//
// Copyright 2017 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//
package driver
import (
"context"
)
type serverModeResponse struct {
Mode ServerMode `json:"mode"`
ArangoError
}
type serverModeRequest struct {
Mode ServerMode `json:"mode"`
}
// ShutdownInfo stores information about shutdown of the coordinator.
type ShutdownInfo struct {
// AQLCursors stores a number of AQL cursors that are still active.
AQLCursors int `json:"AQLcursors"`
// Transactions stores a number of ongoing transactions.
Transactions int `json:"transactions"`
// PendingJobs stores a number of ongoing asynchronous requests.
PendingJobs int `json:"pendingJobs"`
// DoneJobs stores a number of finished asynchronous requests, whose result has not yet been collected.
DoneJobs int `json:"doneJobs"`
// PregelConductors stores a number of ongoing Pregel jobs.
PregelConductors int `json:"pregelConductors"`
// LowPrioOngoingRequests stores a number of ongoing low priority requests.
LowPrioOngoingRequests int `json:"lowPrioOngoingRequests"`
// LowPrioQueuedRequests stores a number of queued low priority requests.
LowPrioQueuedRequests int `json:"lowPrioQueuedRequests"`
// AllClear is set if all operations are closed.
AllClear bool `json:"allClear"`
// SoftShutdownOngoing describes whether a soft shutdown of the Coordinator is in progress.
SoftShutdownOngoing bool `json:"softShutdownOngoing"`
}
// ServerMode returns the current mode in which the server/cluster is operating.
// This call needs ArangoDB 3.3 and up.
func (c *client) ServerMode(ctx context.Context) (ServerMode, error) {
req, err := c.conn.NewRequest("GET", "_admin/server/mode")
if err != nil {
return "", WithStack(err)
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return "", WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return "", WithStack(err)
}
var result serverModeResponse
if err := resp.ParseBody("", &result); err != nil {
return "", WithStack(err)
}
return result.Mode, nil
}
// SetServerMode changes the current mode in which the server/cluster is operating.
// This call needs a client that uses JWT authentication.
// This call needs ArangoDB 3.3 and up.
func (c *client) SetServerMode(ctx context.Context, mode ServerMode) error {
req, err := c.conn.NewRequest("PUT", "_admin/server/mode")
if err != nil {
return WithStack(err)
}
input := serverModeRequest{
Mode: mode,
}
req, err = req.SetBody(input)
if err != nil {
return WithStack(err)
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return WithStack(err)
}
return nil
}
// Logs retrieve logs from server in ArangoDB 3.8.0+ format
func (c *client) Logs(ctx context.Context) (ServerLogs, error) {
req, err := c.conn.NewRequest("GET", "_admin/log/entries")
if err != nil {
return ServerLogs{}, WithStack(err)
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return ServerLogs{}, WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return ServerLogs{}, WithStack(err)
}
var data ServerLogs
if err := resp.ParseBody("", &data); err != nil {
return ServerLogs{}, WithStack(err)
}
return data, nil
}
// Shutdown a specific server, optionally removing it from its cluster.
func (c *client) Shutdown(ctx context.Context, removeFromCluster bool) error {
req, err := c.conn.NewRequest("DELETE", "_admin/shutdown")
if err != nil {
return WithStack(err)
}
if removeFromCluster {
req.SetQuery("remove_from_cluster", "1")
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return WithStack(err)
}
return nil
}
// Metrics returns the metrics of the server in Prometheus format.
func (c *client) Metrics(ctx context.Context) ([]byte, error) {
return c.getMetrics(ctx, "")
}
// MetricsForSingleServer returns the metrics of the specific server in Prometheus format.
// This parameter 'serverID' is only meaningful on Coordinators.
func (c *client) MetricsForSingleServer(ctx context.Context, serverID string) ([]byte, error) {
return c.getMetrics(ctx, serverID)
}
// Metrics returns the metrics of the server in Prometheus format.
func (c *client) getMetrics(ctx context.Context, serverID string) ([]byte, error) {
var rawResponse []byte
ctx = WithRawResponse(ctx, &rawResponse)
req, err := c.conn.NewRequest("GET", "_admin/metrics/v2")
if err != nil {
return rawResponse, WithStack(err)
}
if serverID != "" {
req.SetQuery("serverId", serverID)
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return rawResponse, WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return rawResponse, WithStack(err)
}
return rawResponse, nil
}
// Statistics queries statistics from a specific server.
func (c *client) Statistics(ctx context.Context) (ServerStatistics, error) {
req, err := c.conn.NewRequest("GET", "_admin/statistics")
if err != nil {
return ServerStatistics{}, WithStack(err)
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return ServerStatistics{}, WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return ServerStatistics{}, WithStack(err)
}
var data ServerStatistics
if err := resp.ParseBody("", &data); err != nil {
return ServerStatistics{}, WithStack(err)
}
return data, nil
}
// ShutdownV2 shuts down a specific coordinator, optionally removing it from the cluster with a graceful manner.
// When `graceful` is true then run soft shutdown process and the `ShutdownInfoV2` can be used to check the progress.
// It is available since versions: v3.7.12, v3.8.1, v3.9.0.
func (c *client) ShutdownV2(ctx context.Context, removeFromCluster, graceful bool) error {
req, err := c.conn.NewRequest("DELETE", "_admin/shutdown")
if err != nil {
return WithStack(err)
}
if removeFromCluster {
req.SetQuery("remove_from_cluster", "1")
}
if graceful {
req.SetQuery("soft", "true")
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return WithStack(err)
}
return nil
}
// ShutdownInfoV2 returns information about shutdown progress.
// It is available since versions: v3.7.12, v3.8.1, v3.9.0.
func (c *client) ShutdownInfoV2(ctx context.Context) (ShutdownInfo, error) {
req, err := c.conn.NewRequest("GET", "_admin/shutdown")
if err != nil {
return ShutdownInfo{}, WithStack(err)
}
resp, err := c.conn.Do(ctx, req)
if err != nil {
return ShutdownInfo{}, WithStack(err)
}
if err := resp.CheckStatus(200); err != nil {
return ShutdownInfo{}, WithStack(err)
}
data := ShutdownInfo{}
if err := resp.ParseBody("", &data); err != nil {
return ShutdownInfo{}, WithStack(err)
}
return data, nil
}