github.com/netdata/go.d.plugin@v0.58.1/modules/nginxplus/charts.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package nginxplus
     4  
     5  import (
     6  	"fmt"
     7  	"strings"
     8  
     9  	"github.com/netdata/go.d.plugin/agent/module"
    10  )
    11  
    12  const (
    13  	prioClientConnectionsRate = module.Priority + iota
    14  	prioClientConnectionsCount
    15  
    16  	prioSSLHandshakesRate
    17  	prioSSLHandshakesFailuresRate
    18  	prioSSLVerificationErrorsRate
    19  	prioSSLSessionReusesRate
    20  
    21  	prioHTTPRequestsRate
    22  	prioHTTPRequestsCount
    23  	prioHTTPServerZoneRequestsRate
    24  	prioHTTPLocationZoneRequestsRate
    25  	prioHTTPServerZoneRequestsProcessingCount
    26  	prioHTTPServerZoneRequestsDiscardedRate
    27  	prioHTTPLocationZoneRequestsDiscardedRate
    28  
    29  	prioHTTPServerZoneResponsesPerCodeClassRate
    30  	prioHTTPLocationZoneResponsesPerCodeClassRate
    31  
    32  	prioHTTPServerZoneTrafficRate
    33  	prioHTTPLocationZoneTrafficRate
    34  
    35  	prioHTTPUpstreamPeersCount
    36  	prioHTTPUpstreamZombiesCount
    37  	prioHTTPUpstreamKeepaliveCount
    38  
    39  	prioHTTPUpstreamServerState
    40  	prioHTTPUpstreamServerDowntime
    41  
    42  	prioHTTPUpstreamServerConnectionsCount
    43  
    44  	prioHTTPUpstreamServerRequestsRate
    45  
    46  	prioHTTPUpstreamServerResponsesPerCodeClassRate
    47  
    48  	prioHTTPUpstreamServerResponseTime
    49  	prioHTTPUpstreamServerResponseHeaderTime
    50  
    51  	prioHTTPUpstreamServerTrafficRate
    52  
    53  	prioHTTPCacheState
    54  	prioHTTPCacheIOPS
    55  	prioHTTPCacheIO
    56  	prioHTTPCacheSize
    57  
    58  	prioStreamServerZoneConnectionsRate
    59  	prioStreamServerZoneConnectionsProcessingCount
    60  	prioStreamServerZoneConnectionsDiscardedRate
    61  
    62  	prioStreamServerZoneSessionsPerCodeClassRate
    63  
    64  	prioStreamServerZoneTrafficRate
    65  
    66  	prioStreamUpstreamPeersCount
    67  	prioStreamUpstreamZombiesCount
    68  
    69  	prioStreamUpstreamServerState
    70  	prioStreamUpstreamServerDowntime
    71  
    72  	prioStreamUpstreamServerConnectionsRate
    73  	prioStreamUpstreamServerConnectionsCount
    74  
    75  	prioStreamUpstreamServerTrafficRate
    76  
    77  	prioResolverZoneRequestsRate
    78  	prioResolverZoneResponsesRate
    79  
    80  	prioUptime
    81  )
    82  
    83  var (
    84  	baseCharts = module.Charts{
    85  		clientConnectionsRateChart.Copy(),
    86  		clientConnectionsCountChart.Copy(),
    87  		sslHandshakesRateChart.Copy(),
    88  		sslHandshakesFailuresRateChart.Copy(),
    89  		sslVerificationErrorsRateChart.Copy(),
    90  		sslSessionReusesRateChart.Copy(),
    91  		httpRequestsRateChart.Copy(),
    92  		httpRequestsCountChart.Copy(),
    93  		uptimeChart.Copy(),
    94  	}
    95  
    96  	clientConnectionsRateChart = module.Chart{
    97  		ID:       "client_connections_rate",
    98  		Title:    "Client connections rate",
    99  		Units:    "connections/s",
   100  		Fam:      "connections",
   101  		Ctx:      "nginxplus.client_connections_rate",
   102  		Priority: prioClientConnectionsRate,
   103  		Dims: module.Dims{
   104  			{ID: "connections_accepted", Name: "accepted", Algo: module.Incremental},
   105  			{ID: "connections_dropped", Name: "dropped", Algo: module.Incremental},
   106  		},
   107  	}
   108  	clientConnectionsCountChart = module.Chart{
   109  		ID:       "client_connections_count",
   110  		Title:    "Client connections",
   111  		Units:    "connections",
   112  		Fam:      "connections",
   113  		Ctx:      "nginxplus.client_connections_count",
   114  		Priority: prioClientConnectionsCount,
   115  		Dims: module.Dims{
   116  			{ID: "connections_active", Name: "active"},
   117  			{ID: "connections_idle", Name: "idle"},
   118  		},
   119  	}
   120  	sslHandshakesRateChart = module.Chart{
   121  		ID:       "ssl_handshakes_rate",
   122  		Title:    "SSL handshakes rate",
   123  		Units:    "handshakes/s",
   124  		Fam:      "ssl",
   125  		Ctx:      "nginxplus.ssl_handshakes_rate",
   126  		Priority: prioSSLHandshakesRate,
   127  		Dims: module.Dims{
   128  			{ID: "ssl_handshakes", Name: "successful", Algo: module.Incremental},
   129  			{ID: "ssl_handshakes_failed", Name: "failed", Algo: module.Incremental},
   130  		},
   131  	}
   132  	sslHandshakesFailuresRateChart = module.Chart{
   133  		ID:       "ssl_handshakes_failures_rate",
   134  		Title:    "SSL handshakes failures rate",
   135  		Units:    "failures/s",
   136  		Fam:      "ssl",
   137  		Ctx:      "nginxplus.ssl_handshakes_failures_rate",
   138  		Priority: prioSSLHandshakesFailuresRate,
   139  		Type:     module.Stacked,
   140  		Dims: module.Dims{
   141  			{ID: "ssl_no_common_protocol", Name: "no_common_protocol", Algo: module.Incremental},
   142  			{ID: "ssl_no_common_cipher", Name: "no_common_cipher", Algo: module.Incremental},
   143  			{ID: "ssl_handshake_timeout", Name: "timeout", Algo: module.Incremental},
   144  			{ID: "ssl_peer_rejected_cert", Name: "peer_rejected_cert", Algo: module.Incremental},
   145  		},
   146  	}
   147  	sslVerificationErrorsRateChart = module.Chart{
   148  		ID:       "ssl_verification_errors_rate",
   149  		Title:    "SSL verification errors rate",
   150  		Units:    "errors/s",
   151  		Fam:      "ssl",
   152  		Ctx:      "nginxplus.ssl_verification_errors_rate",
   153  		Priority: prioSSLVerificationErrorsRate,
   154  		Type:     module.Stacked,
   155  		Dims: module.Dims{
   156  			{ID: "ssl_verify_failures_no_cert", Name: "no_cert", Algo: module.Incremental},
   157  			{ID: "ssl_verify_failures_expired_cert", Name: "expired_cert", Algo: module.Incremental},
   158  			{ID: "ssl_verify_failures_revoked_cert", Name: "revoked_cert", Algo: module.Incremental},
   159  			{ID: "ssl_verify_failures_hostname_mismatch", Name: "hostname_mismatch", Algo: module.Incremental},
   160  			{ID: "ssl_verify_failures_other", Name: "other", Algo: module.Incremental},
   161  		},
   162  	}
   163  	sslSessionReusesRateChart = module.Chart{
   164  		ID:       "ssl_session_reuses_rate",
   165  		Title:    "Session reuses during SSL handshake",
   166  		Units:    "reuses/s",
   167  		Fam:      "ssl",
   168  		Ctx:      "nginxplus.ssl_session_reuses_rate",
   169  		Priority: prioSSLSessionReusesRate,
   170  		Dims: module.Dims{
   171  			{ID: "ssl_session_reuses", Name: "ssl_session", Algo: module.Incremental},
   172  		},
   173  	}
   174  	httpRequestsRateChart = module.Chart{
   175  		ID:       "http_requests_rate",
   176  		Title:    "HTTP requests rate",
   177  		Units:    "requests/s",
   178  		Fam:      "http requests",
   179  		Ctx:      "nginxplus.http_requests_rate",
   180  		Priority: prioHTTPRequestsRate,
   181  		Dims: module.Dims{
   182  			{ID: "http_requests_total", Name: "requests", Algo: module.Incremental},
   183  		},
   184  	}
   185  	httpRequestsCountChart = module.Chart{
   186  		ID:       "http_requests_count",
   187  		Title:    "HTTP requests",
   188  		Units:    "requests",
   189  		Fam:      "http requests",
   190  		Ctx:      "nginxplus.http_requests_count",
   191  		Priority: prioHTTPRequestsCount,
   192  		Dims: module.Dims{
   193  			{ID: "http_requests_current", Name: "requests"},
   194  		},
   195  	}
   196  	uptimeChart = module.Chart{
   197  		ID:       "uptime",
   198  		Title:    "Uptime",
   199  		Units:    "seconds",
   200  		Fam:      "uptime",
   201  		Ctx:      "nginxplus.uptime",
   202  		Priority: prioUptime,
   203  		Dims: module.Dims{
   204  			{ID: "uptime", Name: "uptime"},
   205  		},
   206  	}
   207  )
   208  
   209  var (
   210  	httpServerZoneChartsTmpl = module.Charts{
   211  		httpServerZoneRequestsRateChartTmpl.Copy(),
   212  		httpServerZoneResponsesPerCodeClassRateChartTmpl.Copy(),
   213  		httpServerZoneTrafficRateChartTmpl.Copy(),
   214  		httpServerZoneRequestsProcessingCountChartTmpl.Copy(),
   215  		httpServerZoneRequestsDiscardedRateChartTmpl.Copy(),
   216  	}
   217  	httpServerZoneRequestsRateChartTmpl = module.Chart{
   218  		ID:       "http_server_zone_%s_requests_rate",
   219  		Title:    "HTTP Server Zone requests rate",
   220  		Units:    "requests/s",
   221  		Fam:      "http requests",
   222  		Ctx:      "nginxplus.http_server_zone_requests_rate",
   223  		Priority: prioHTTPServerZoneRequestsRate,
   224  		Dims: module.Dims{
   225  			{ID: "http_server_zone_%s_requests", Name: "requests", Algo: module.Incremental},
   226  		},
   227  	}
   228  	httpServerZoneResponsesPerCodeClassRateChartTmpl = module.Chart{
   229  		ID:       "http_server_zone_%s_responses_per_code_class_rate",
   230  		Title:    "HTTP Server Zone responses rate",
   231  		Units:    "responses/s",
   232  		Fam:      "http responses",
   233  		Ctx:      "nginxplus.http_server_zone_responses_per_code_class_rate",
   234  		Priority: prioHTTPServerZoneResponsesPerCodeClassRate,
   235  		Type:     module.Stacked,
   236  		Dims: module.Dims{
   237  			{ID: "http_server_zone_%s_responses_1xx", Name: "1xx", Algo: module.Incremental},
   238  			{ID: "http_server_zone_%s_responses_2xx", Name: "2xx", Algo: module.Incremental},
   239  			{ID: "http_server_zone_%s_responses_3xx", Name: "3xx", Algo: module.Incremental},
   240  			{ID: "http_server_zone_%s_responses_4xx", Name: "4xx", Algo: module.Incremental},
   241  			{ID: "http_server_zone_%s_responses_5xx", Name: "5xx", Algo: module.Incremental},
   242  		},
   243  	}
   244  	httpServerZoneTrafficRateChartTmpl = module.Chart{
   245  		ID:       "http_server_zone_%s_traffic_rate",
   246  		Title:    "HTTP Server Zone traffic",
   247  		Units:    "bytes/s",
   248  		Fam:      "http traffic",
   249  		Ctx:      "nginxplus.http_server_zone_traffic_rate",
   250  		Priority: prioHTTPServerZoneTrafficRate,
   251  		Type:     module.Area,
   252  		Dims: module.Dims{
   253  			{ID: "http_server_zone_%s_bytes_received", Name: "received", Algo: module.Incremental},
   254  			{ID: "http_server_zone_%s_bytes_sent", Name: "sent", Algo: module.Incremental, Mul: -1},
   255  		},
   256  	}
   257  	httpServerZoneRequestsProcessingCountChartTmpl = module.Chart{
   258  		ID:       "http_server_zone_%s_requests_processing_count",
   259  		Title:    "HTTP Server Zone currently processed requests",
   260  		Units:    "requests",
   261  		Fam:      "http requests",
   262  		Ctx:      "nginxplus.http_server_zone_requests_processing_count",
   263  		Priority: prioHTTPServerZoneRequestsProcessingCount,
   264  		Dims: module.Dims{
   265  			{ID: "http_server_zone_%s_requests_processing", Name: "processing"},
   266  		},
   267  	}
   268  	httpServerZoneRequestsDiscardedRateChartTmpl = module.Chart{
   269  		ID:       "http_server_zone_%s_requests_discarded_rate",
   270  		Title:    "HTTP Server Zone requests discarded rate",
   271  		Units:    "requests/s",
   272  		Fam:      "http requests",
   273  		Ctx:      "nginxplus.http_server_zone_requests_discarded_rate",
   274  		Priority: prioHTTPServerZoneRequestsDiscardedRate,
   275  		Dims: module.Dims{
   276  			{ID: "http_server_zone_%s_requests_discarded", Name: "discarded", Algo: module.Incremental},
   277  		},
   278  	}
   279  )
   280  
   281  var (
   282  	httpLocationZoneChartsTmpl = module.Charts{
   283  		httpLocationZoneRequestsRateChartTmpl.Copy(),
   284  		httpLocationZoneRequestsDiscardedRateChartTmpl.Copy(),
   285  		httpLocationZoneTrafficRateChartTmpl.Copy(),
   286  		httpLocationZoneResponsesPerCodeClassRateChartTmpl.Copy(),
   287  	}
   288  	httpLocationZoneRequestsRateChartTmpl = module.Chart{
   289  		ID:       "http_location_zone_%s_requests_rate",
   290  		Title:    "HTTP Location Zone requests rate",
   291  		Units:    "requests/s",
   292  		Fam:      "http requests",
   293  		Ctx:      "nginxplus.http_location_zone_requests_rate",
   294  		Priority: prioHTTPLocationZoneRequestsRate,
   295  		Dims: module.Dims{
   296  			{ID: "http_location_zone_%s_requests", Name: "requests", Algo: module.Incremental},
   297  		},
   298  	}
   299  	httpLocationZoneResponsesPerCodeClassRateChartTmpl = module.Chart{
   300  		ID:       "http_location_zone_%s_responses_per_code_class_rate",
   301  		Title:    "HTTP Location Zone responses rate",
   302  		Units:    "responses/s",
   303  		Fam:      "http responses",
   304  		Ctx:      "nginxplus.http_location_zone_responses_per_code_class_rate",
   305  		Priority: prioHTTPLocationZoneResponsesPerCodeClassRate,
   306  		Type:     module.Stacked,
   307  		Dims: module.Dims{
   308  			{ID: "http_location_zone_%s_responses_1xx", Name: "1xx", Algo: module.Incremental},
   309  			{ID: "http_location_zone_%s_responses_2xx", Name: "2xx", Algo: module.Incremental},
   310  			{ID: "http_location_zone_%s_responses_3xx", Name: "3xx", Algo: module.Incremental},
   311  			{ID: "http_location_zone_%s_responses_4xx", Name: "4xx", Algo: module.Incremental},
   312  			{ID: "http_location_zone_%s_responses_5xx", Name: "5xx", Algo: module.Incremental},
   313  		},
   314  	}
   315  	httpLocationZoneTrafficRateChartTmpl = module.Chart{
   316  		ID:       "http_location_zone_%s_traffic_rate",
   317  		Title:    "HTTP Location Zone traffic rate",
   318  		Units:    "bytes/s",
   319  		Fam:      "http traffic",
   320  		Ctx:      "nginxplus.http_location_zone_traffic_rate",
   321  		Priority: prioHTTPLocationZoneTrafficRate,
   322  		Type:     module.Area,
   323  		Dims: module.Dims{
   324  			{ID: "http_location_zone_%s_bytes_received", Name: "received", Algo: module.Incremental},
   325  			{ID: "http_location_zone_%s_bytes_sent", Name: "sent", Algo: module.Incremental, Mul: -1},
   326  		},
   327  	}
   328  	httpLocationZoneRequestsDiscardedRateChartTmpl = module.Chart{
   329  		ID:       "http_location_zone_%s_requests_discarded_rate",
   330  		Title:    "HTTP Location Zone requests discarded rate",
   331  		Units:    "requests/s",
   332  		Fam:      "http requests",
   333  		Ctx:      "nginxplus.http_location_zone_requests_discarded_rate",
   334  		Priority: prioHTTPLocationZoneRequestsDiscardedRate,
   335  		Dims: module.Dims{
   336  			{ID: "http_location_zone_%s_requests_discarded", Name: "discarded", Algo: module.Incremental},
   337  		},
   338  	}
   339  )
   340  
   341  var (
   342  	httpUpstreamChartsTmpl = module.Charts{
   343  		httpUpstreamPeersCountChartTmpl.Copy(),
   344  		httpUpstreamZombiesCountChartTmpl.Copy(),
   345  		httpUpstreamKeepaliveCountChartTmpl.Copy(),
   346  	}
   347  	httpUpstreamPeersCountChartTmpl = module.Chart{
   348  		ID:       "http_upstream_%s_zone_%s_peers_count",
   349  		Title:    "HTTP Upstream peers",
   350  		Units:    "peers",
   351  		Fam:      "http upstream",
   352  		Ctx:      "nginxplus.http_upstream_peers_count",
   353  		Priority: prioHTTPUpstreamPeersCount,
   354  		Dims: module.Dims{
   355  			{ID: "http_upstream_%s_zone_%s_peers", Name: "peers"},
   356  		},
   357  	}
   358  	httpUpstreamZombiesCountChartTmpl = module.Chart{
   359  		ID:       "http_upstream_%s_zone_%s_zombies_count",
   360  		Title:    "HTTP Upstream zombies",
   361  		Units:    "servers",
   362  		Fam:      "http upstream",
   363  		Ctx:      "nginxplus.http_upstream_zombies_count",
   364  		Priority: prioHTTPUpstreamZombiesCount,
   365  		Dims: module.Dims{
   366  			{ID: "http_upstream_%s_zone_%s_zombies", Name: "zombie"},
   367  		},
   368  	}
   369  	httpUpstreamKeepaliveCountChartTmpl = module.Chart{
   370  		ID:       "http_upstream_%s_zone_%s_keepalive_count",
   371  		Title:    "HTTP Upstream keepalive",
   372  		Units:    "connections",
   373  		Fam:      "http upstream",
   374  		Ctx:      "nginxplus.http_upstream_keepalive_count",
   375  		Priority: prioHTTPUpstreamKeepaliveCount,
   376  		Dims: module.Dims{
   377  			{ID: "http_upstream_%s_zone_%s_keepalive", Name: "keepalive"},
   378  		},
   379  	}
   380  
   381  	httpUpstreamServerChartsTmpl = module.Charts{
   382  		httpUpstreamServerRequestsRateChartTmpl.Copy(),
   383  		httpUpstreamServerResponsesPerCodeClassRateChartTmpl.Copy(),
   384  		httpUpstreamServerResponseTimeChartTmpl.Copy(),
   385  		httpUpstreamServerResponseHeaderTimeChartTmpl.Copy(),
   386  		httpUpstreamServerTrafficRateChartTmpl.Copy(),
   387  		httpUpstreamServerStateChartTmpl.Copy(),
   388  		httpUpstreamServerDowntimeChartTmpl.Copy(),
   389  		httpUpstreamServerConnectionsCountChartTmpl.Copy(),
   390  	}
   391  	httpUpstreamServerRequestsRateChartTmpl = module.Chart{
   392  		ID:       "http_upstream_%s_server_%s_zone_%s_requests_rate",
   393  		Title:    "HTTP Upstream Server requests",
   394  		Units:    "requests/s",
   395  		Fam:      "http upstream requests",
   396  		Ctx:      "nginxplus.http_upstream_server_requests_rate",
   397  		Priority: prioHTTPUpstreamServerRequestsRate,
   398  		Dims: module.Dims{
   399  			{ID: "http_upstream_%s_server_%s_zone_%s_requests", Name: "requests", Algo: module.Incremental},
   400  		},
   401  	}
   402  	httpUpstreamServerResponsesPerCodeClassRateChartTmpl = module.Chart{
   403  		ID:       "http_upstream_%s_server_%s_zone_%s_responses_per_code_class_rate",
   404  		Title:    "HTTP Upstream Server responses",
   405  		Units:    "responses/s",
   406  		Fam:      "http upstream responses",
   407  		Ctx:      "nginxplus.http_upstream_server_responses_per_code_class_rate",
   408  		Priority: prioHTTPUpstreamServerResponsesPerCodeClassRate,
   409  		Type:     module.Stacked,
   410  		Dims: module.Dims{
   411  			{ID: "http_upstream_%s_server_%s_zone_%s_responses_1xx", Name: "1xx", Algo: module.Incremental},
   412  			{ID: "http_upstream_%s_server_%s_zone_%s_responses_2xx", Name: "2xx", Algo: module.Incremental},
   413  			{ID: "http_upstream_%s_server_%s_zone_%s_responses_3xx", Name: "3xx", Algo: module.Incremental},
   414  			{ID: "http_upstream_%s_server_%s_zone_%s_responses_4xx", Name: "4xx", Algo: module.Incremental},
   415  			{ID: "http_upstream_%s_server_%s_zone_%s_responses_5xx", Name: "5xx", Algo: module.Incremental},
   416  		},
   417  	}
   418  	httpUpstreamServerResponseTimeChartTmpl = module.Chart{
   419  		ID:       "http_upstream_%s_server_%s_zone_%s_response_time",
   420  		Title:    "HTTP Upstream Server average response time",
   421  		Units:    "milliseconds",
   422  		Fam:      "http upstream response time",
   423  		Ctx:      "nginxplus.http_upstream_server_response_time",
   424  		Priority: prioHTTPUpstreamServerResponseTime,
   425  		Dims: module.Dims{
   426  			{ID: "http_upstream_%s_server_%s_zone_%s_response_time", Name: "response"},
   427  		},
   428  	}
   429  	httpUpstreamServerResponseHeaderTimeChartTmpl = module.Chart{
   430  		ID:       "http_upstream_%s_server_%s_zone_%s_response_header_time",
   431  		Title:    "HTTP Upstream Server average response header time",
   432  		Units:    "milliseconds",
   433  		Fam:      "http upstream response time",
   434  		Ctx:      "nginxplus.http_upstream_server_response_header_time",
   435  		Priority: prioHTTPUpstreamServerResponseHeaderTime,
   436  		Dims: module.Dims{
   437  			{ID: "http_upstream_%s_server_%s_zone_%s_header_time", Name: "header"},
   438  		},
   439  	}
   440  	httpUpstreamServerTrafficRateChartTmpl = module.Chart{
   441  		ID:       "http_upstream_%s_server_%s_zone_%s_traffic_rate",
   442  		Title:    "HTTP Upstream Server traffic rate",
   443  		Units:    "bytes/s",
   444  		Fam:      "http upstream traffic",
   445  		Ctx:      "nginxplus.http_upstream_server_traffic_rate",
   446  		Priority: prioHTTPUpstreamServerTrafficRate,
   447  		Type:     module.Area,
   448  		Dims: module.Dims{
   449  			{ID: "http_upstream_%s_server_%s_zone_%s_bytes_received", Name: "received", Algo: module.Incremental},
   450  			{ID: "http_upstream_%s_server_%s_zone_%s_bytes_sent", Name: "sent", Algo: module.Incremental, Mul: -1},
   451  		},
   452  	}
   453  	httpUpstreamServerStateChartTmpl = module.Chart{
   454  		ID:       "http_upstream_%s_server_%s_zone_%s_state",
   455  		Title:    "HTTP Upstream Server state",
   456  		Units:    "state",
   457  		Fam:      "http upstream state",
   458  		Ctx:      "nginxplus.http_upstream_server_state",
   459  		Priority: prioHTTPUpstreamServerState,
   460  		Dims: module.Dims{
   461  			{ID: "http_upstream_%s_server_%s_zone_%s_state_up", Name: "up"},
   462  			{ID: "http_upstream_%s_server_%s_zone_%s_state_down", Name: "down"},
   463  			{ID: "http_upstream_%s_server_%s_zone_%s_state_draining", Name: "draining"},
   464  			{ID: "http_upstream_%s_server_%s_zone_%s_state_unavail", Name: "unavail"},
   465  			{ID: "http_upstream_%s_server_%s_zone_%s_state_checking", Name: "checking"},
   466  			{ID: "http_upstream_%s_server_%s_zone_%s_state_unhealthy", Name: "unhealthy"},
   467  		},
   468  	}
   469  	httpUpstreamServerConnectionsCountChartTmpl = module.Chart{
   470  		ID:       "http_upstream_%s_server_%s_zone_%s_connection_count",
   471  		Title:    "HTTP Upstream Server connections",
   472  		Units:    "connections",
   473  		Fam:      "http upstream connections",
   474  		Ctx:      "nginxplus.http_upstream_server_connections_count",
   475  		Priority: prioHTTPUpstreamServerConnectionsCount,
   476  		Dims: module.Dims{
   477  			{ID: "http_upstream_%s_server_%s_zone_%s_active", Name: "active"},
   478  		},
   479  	}
   480  	httpUpstreamServerDowntimeChartTmpl = module.Chart{
   481  		ID:       "http_upstream_%s_server_%s_zone_%s_downtime",
   482  		Title:    "HTTP Upstream Server downtime",
   483  		Units:    "seconds",
   484  		Fam:      "http upstream state",
   485  		Ctx:      "nginxplus.http_upstream_server_downtime",
   486  		Priority: prioHTTPUpstreamServerDowntime,
   487  		Dims: module.Dims{
   488  			{ID: "http_upstream_%s_server_%s_zone_%s_downtime", Name: "downtime"},
   489  		},
   490  	}
   491  )
   492  
   493  var (
   494  	httpCacheChartsTmpl = module.Charts{
   495  		httpCacheStateChartTmpl.Copy(),
   496  		httpCacheIOPSChartTmpl.Copy(),
   497  		httpCacheIOChartTmpl.Copy(),
   498  		httpCacheSizeChartTmpl.Copy(),
   499  	}
   500  	httpCacheStateChartTmpl = module.Chart{
   501  		ID:       "http_cache_%s_state",
   502  		Title:    "HTTP Cache state",
   503  		Units:    "state",
   504  		Fam:      "http cache",
   505  		Ctx:      "nginxplus.http_cache_state",
   506  		Priority: prioHTTPCacheState,
   507  		Dims: module.Dims{
   508  			{ID: "http_cache_%s_state_warm", Name: "warm"},
   509  			{ID: "http_cache_%s_state_cold", Name: "cold"},
   510  		},
   511  	}
   512  	httpCacheSizeChartTmpl = module.Chart{
   513  		ID:       "http_cache_%s_size",
   514  		Title:    "HTTP Cache size",
   515  		Units:    "bytes",
   516  		Fam:      "http cache",
   517  		Ctx:      "nginxplus.http_cache_size",
   518  		Priority: prioHTTPCacheSize,
   519  		Dims: module.Dims{
   520  			{ID: "http_cache_%s_size", Name: "size"},
   521  		},
   522  	}
   523  	httpCacheIOPSChartTmpl = module.Chart{
   524  		ID:       "http_cache_%s_iops",
   525  		Title:    "HTTP Cache IOPS",
   526  		Units:    "responses/s",
   527  		Fam:      "http cache",
   528  		Ctx:      "nginxplus.http_cache_iops",
   529  		Priority: prioHTTPCacheIOPS,
   530  		Dims: module.Dims{
   531  			{ID: "http_cache_%s_served_responses", Name: "served", Algo: module.Incremental},
   532  			{ID: "http_cache_%s_written_responses", Name: "written", Algo: module.Incremental},
   533  			{ID: "http_cache_%s_bypassed_responses", Name: "bypassed", Algo: module.Incremental},
   534  		},
   535  	}
   536  	httpCacheIOChartTmpl = module.Chart{
   537  		ID:       "http_cache_%s_io",
   538  		Title:    "HTTP Cache IO",
   539  		Units:    "bytes/s",
   540  		Fam:      "http cache",
   541  		Ctx:      "nginxplus.http_cache_io",
   542  		Priority: prioHTTPCacheIO,
   543  		Dims: module.Dims{
   544  			{ID: "http_cache_%s_served_bytes", Name: "served", Algo: module.Incremental},
   545  			{ID: "http_cache_%s_written_bytes", Name: "written", Algo: module.Incremental},
   546  			{ID: "http_cache_%s_bypassed_bytes", Name: "bypassed", Algo: module.Incremental},
   547  		},
   548  	}
   549  )
   550  
   551  var (
   552  	streamServerZoneChartsTmpl = module.Charts{
   553  		streamServerZoneConnectionsRateChartTmpl.Copy(),
   554  		streamServerZoneTrafficRateChartTmpl.Copy(),
   555  		streamServerZoneSessionsPerCodeClassRateChartTmpl.Copy(),
   556  		streamServerZoneConnectionsProcessingCountRateChartTmpl.Copy(),
   557  		streamServerZoneConnectionsDiscardedRateChartTmpl.Copy(),
   558  	}
   559  	streamServerZoneConnectionsRateChartTmpl = module.Chart{
   560  		ID:       "stream_server_zone_%s_connections_rate",
   561  		Title:    "Stream Server Zone connections rate",
   562  		Units:    "connections/s",
   563  		Fam:      "stream connections",
   564  		Ctx:      "nginxplus.stream_server_zone_connections_rate",
   565  		Priority: prioStreamServerZoneConnectionsRate,
   566  		Dims: module.Dims{
   567  			{ID: "stream_server_zone_%s_connections", Name: "accepted", Algo: module.Incremental},
   568  		},
   569  	}
   570  	streamServerZoneSessionsPerCodeClassRateChartTmpl = module.Chart{
   571  		ID:       "stream_server_zone_%s_sessions_per_code_class_rate",
   572  		Title:    "Stream Server Zone sessions rate",
   573  		Units:    "sessions/s",
   574  		Fam:      "stream sessions",
   575  		Ctx:      "nginxplus.stream_server_zone_sessions_per_code_class_rate",
   576  		Priority: prioStreamServerZoneSessionsPerCodeClassRate,
   577  		Type:     module.Stacked,
   578  		Dims: module.Dims{
   579  			{ID: "stream_server_zone_%s_sessions_2xx", Name: "2xx", Algo: module.Incremental},
   580  			{ID: "stream_server_zone_%s_sessions_4xx", Name: "4xx", Algo: module.Incremental},
   581  			{ID: "stream_server_zone_%s_sessions_5xx", Name: "5xx", Algo: module.Incremental},
   582  		},
   583  	}
   584  	streamServerZoneTrafficRateChartTmpl = module.Chart{
   585  		ID:       "stream_server_zone_%s_traffic_rate",
   586  		Title:    "Stream Server Zone traffic rate",
   587  		Units:    "bytes/s",
   588  		Fam:      "stream traffic",
   589  		Ctx:      "nginxplus.stream_server_zone_traffic_rate",
   590  		Priority: prioStreamServerZoneTrafficRate,
   591  		Type:     module.Area,
   592  		Dims: module.Dims{
   593  			{ID: "stream_server_zone_%s_bytes_received", Name: "received", Algo: module.Incremental},
   594  			{ID: "stream_server_zone_%s_bytes_sent", Name: "sent", Algo: module.Incremental, Mul: -1},
   595  		},
   596  	}
   597  	streamServerZoneConnectionsProcessingCountRateChartTmpl = module.Chart{
   598  		ID:       "stream_server_zone_%s_connections_processing_count",
   599  		Title:    "Stream Server Zone connections processed",
   600  		Units:    "connections",
   601  		Fam:      "stream connections",
   602  		Ctx:      "nginxplus.stream_server_zone_connections_processing_count",
   603  		Priority: prioStreamServerZoneConnectionsProcessingCount,
   604  		Dims: module.Dims{
   605  			{ID: "stream_server_zone_%s_connections_processing", Name: "processing"},
   606  		},
   607  	}
   608  	streamServerZoneConnectionsDiscardedRateChartTmpl = module.Chart{
   609  		ID:       "stream_server_zone_%s_connections_discarded_rate",
   610  		Title:    "Stream Server Zone connections discarded",
   611  		Units:    "connections/s",
   612  		Fam:      "stream connections",
   613  		Ctx:      "nginxplus.stream_server_zone_connections_discarded_rate",
   614  		Priority: prioStreamServerZoneConnectionsDiscardedRate,
   615  		Dims: module.Dims{
   616  			{ID: "stream_server_zone_%s_connections_discarded", Name: "discarded", Algo: module.Incremental},
   617  		},
   618  	}
   619  )
   620  
   621  var (
   622  	streamUpstreamChartsTmpl = module.Charts{
   623  		streamUpstreamPeersCountChartTmpl.Copy(),
   624  		streamUpstreamZombiesCountChartTmpl.Copy(),
   625  	}
   626  	streamUpstreamPeersCountChartTmpl = module.Chart{
   627  		ID:       "stream_upstream_%s_zone_%s_peers_count",
   628  		Title:    "Stream Upstream peers",
   629  		Units:    "peers",
   630  		Fam:      "stream upstream",
   631  		Ctx:      "nginxplus.stream_upstream_peers_count",
   632  		Priority: prioStreamUpstreamPeersCount,
   633  		Dims: module.Dims{
   634  			{ID: "stream_upstream_%s_zone_%s_peers", Name: "peers"},
   635  		},
   636  	}
   637  	streamUpstreamZombiesCountChartTmpl = module.Chart{
   638  		ID:       "stream_upstream_%s_zone_%s_zombies_count",
   639  		Title:    "Stream Upstream zombies",
   640  		Units:    "servers",
   641  		Fam:      "stream upstream",
   642  		Ctx:      "nginxplus.stream_upstream_zombies_count",
   643  		Priority: prioStreamUpstreamZombiesCount,
   644  		Dims: module.Dims{
   645  			{ID: "stream_upstream_%s_zone_%s_zombies", Name: "zombie"},
   646  		},
   647  	}
   648  
   649  	streamUpstreamServerChartsTmpl = module.Charts{
   650  		streamUpstreamServerConnectionsRateChartTmpl.Copy(),
   651  		streamUpstreamServerTrafficRateChartTmpl.Copy(),
   652  		streamUpstreamServerConnectionsCountChartTmpl.Copy(),
   653  		streamUpstreamServerStateChartTmpl.Copy(),
   654  		streamUpstreamServerDowntimeChartTmpl.Copy(),
   655  	}
   656  	streamUpstreamServerConnectionsRateChartTmpl = module.Chart{
   657  		ID:       "stream_upstream_%s_server_%s_zone_%s_connection_rate",
   658  		Title:    "Stream Upstream Server connections",
   659  		Units:    "connections/s",
   660  		Fam:      "stream upstream connections",
   661  		Ctx:      "nginxplus.stream_upstream_server_connections_rate",
   662  		Priority: prioStreamUpstreamServerConnectionsRate,
   663  		Dims: module.Dims{
   664  			{ID: "stream_upstream_%s_server_%s_zone_%s_connections", Name: "forwarded", Algo: module.Incremental},
   665  		},
   666  	}
   667  	streamUpstreamServerTrafficRateChartTmpl = module.Chart{
   668  		ID:       "stream_upstream_%s_server_%s_zone_%s_traffic_rate",
   669  		Title:    "Stream Upstream Server traffic rate",
   670  		Units:    "bytes/s",
   671  		Fam:      "stream upstream traffic",
   672  		Ctx:      "nginxplus.stream_upstream_server_traffic_rate",
   673  		Priority: prioStreamUpstreamServerTrafficRate,
   674  		Type:     module.Area,
   675  		Dims: module.Dims{
   676  			{ID: "stream_upstream_%s_server_%s_zone_%s_bytes_received", Name: "received", Algo: module.Incremental},
   677  			{ID: "stream_upstream_%s_server_%s_zone_%s_bytes_sent", Name: "sent", Algo: module.Incremental, Mul: -1},
   678  		},
   679  	}
   680  	streamUpstreamServerStateChartTmpl = module.Chart{
   681  		ID:       "stream_upstream_%s_server_%s_zone_%s_state",
   682  		Title:    "Stream Upstream Server state",
   683  		Units:    "state",
   684  		Fam:      "stream upstream state",
   685  		Ctx:      "nginxplus.stream_upstream_server_state",
   686  		Priority: prioStreamUpstreamServerState,
   687  		Dims: module.Dims{
   688  			{ID: "stream_upstream_%s_server_%s_zone_%s_state_up", Name: "up"},
   689  			{ID: "stream_upstream_%s_server_%s_zone_%s_state_down", Name: "down"},
   690  			{ID: "stream_upstream_%s_server_%s_zone_%s_state_unavail", Name: "unavail"},
   691  			{ID: "stream_upstream_%s_server_%s_zone_%s_state_checking", Name: "checking"},
   692  			{ID: "stream_upstream_%s_server_%s_zone_%s_state_unhealthy", Name: "unhealthy"},
   693  		},
   694  	}
   695  	streamUpstreamServerDowntimeChartTmpl = module.Chart{
   696  		ID:       "stream_upstream_%s_server_%s_zone_%s_downtime",
   697  		Title:    "Stream Upstream Server downtime",
   698  		Units:    "seconds",
   699  		Fam:      "stream upstream state",
   700  		Ctx:      "nginxplus.stream_upstream_server_downtime",
   701  		Priority: prioStreamUpstreamServerDowntime,
   702  		Dims: module.Dims{
   703  			{ID: "stream_upstream_%s_server_%s_zone_%s_downtime", Name: "downtime"},
   704  		},
   705  	}
   706  	streamUpstreamServerConnectionsCountChartTmpl = module.Chart{
   707  		ID:       "stream_upstream_%s_server_%s_zone_%s_connection_count",
   708  		Title:    "Stream Upstream Server connections",
   709  		Units:    "connections",
   710  		Fam:      "stream upstream connections",
   711  		Ctx:      "nginxplus.stream_upstream_server_connections_count",
   712  		Priority: prioStreamUpstreamServerConnectionsCount,
   713  		Dims: module.Dims{
   714  			{ID: "stream_upstream_%s_server_%s_zone_%s_active", Name: "active"},
   715  		},
   716  	}
   717  )
   718  
   719  var (
   720  	resolverZoneChartsTmpl = module.Charts{
   721  		resolverZoneRequestsRateChartTmpl.Copy(),
   722  		resolverZoneResponsesRateChartTmpl.Copy(),
   723  	}
   724  	resolverZoneRequestsRateChartTmpl = module.Chart{
   725  		ID:       "resolver_zone_%s_requests_rate",
   726  		Title:    "Resolver requests rate",
   727  		Units:    "requests/s",
   728  		Fam:      "resolver requests",
   729  		Ctx:      "nginxplus.resolver_zone_requests_rate",
   730  		Priority: prioResolverZoneRequestsRate,
   731  		Type:     module.Stacked,
   732  		Dims: module.Dims{
   733  			{ID: "resolver_zone_%s_requests_name", Name: "name", Algo: module.Incremental},
   734  			{ID: "resolver_zone_%s_requests_srv", Name: "srv", Algo: module.Incremental},
   735  			{ID: "resolver_zone_%s_requests_addr", Name: "addr", Algo: module.Incremental},
   736  		},
   737  	}
   738  	resolverZoneResponsesRateChartTmpl = module.Chart{
   739  		ID:       "resolver_zone_%s_responses_rate",
   740  		Title:    "Resolver responses rate",
   741  		Units:    "responses/s",
   742  		Fam:      "resolver responses",
   743  		Ctx:      "nginxplus.resolver_zone_responses_rate",
   744  		Priority: prioResolverZoneResponsesRate,
   745  		Type:     module.Stacked,
   746  		Dims: module.Dims{
   747  			{ID: "resolver_zone_%s_responses_noerror", Name: "noerror", Algo: module.Incremental},
   748  			{ID: "resolver_zone_%s_responses_formerr", Name: "formerr", Algo: module.Incremental},
   749  			{ID: "resolver_zone_%s_responses_servfail", Name: "servfail", Algo: module.Incremental},
   750  			{ID: "resolver_zone_%s_responses_nxdomain", Name: "nxdomain", Algo: module.Incremental},
   751  			{ID: "resolver_zone_%s_responses_notimp", Name: "notimp", Algo: module.Incremental},
   752  			{ID: "resolver_zone_%s_responses_refused", Name: "refused", Algo: module.Incremental},
   753  			{ID: "resolver_zone_%s_responses_timedout", Name: "timedout", Algo: module.Incremental},
   754  			{ID: "resolver_zone_%s_responses_unknown", Name: "unknown", Algo: module.Incremental},
   755  		},
   756  	}
   757  )
   758  
   759  func (n *NginxPlus) addHTTPCacheCharts(name string) {
   760  	charts := httpCacheChartsTmpl.Copy()
   761  
   762  	for _, chart := range *charts {
   763  		chart.ID = fmt.Sprintf(chart.ID, name)
   764  		chart.Labels = []module.Label{
   765  			{Key: "http_cache", Value: name},
   766  		}
   767  		for _, dim := range chart.Dims {
   768  			dim.ID = fmt.Sprintf(dim.ID, name)
   769  		}
   770  	}
   771  
   772  	if err := n.Charts().Add(*charts...); err != nil {
   773  		n.Warning(err)
   774  	}
   775  }
   776  
   777  func (n *NginxPlus) removeHTTPCacheCharts(name string) {
   778  	px := fmt.Sprintf("http_cache_%s_", name)
   779  	n.removeCharts(px)
   780  }
   781  
   782  func (n *NginxPlus) addHTTPServerZoneCharts(zone string) {
   783  	charts := httpServerZoneChartsTmpl.Copy()
   784  
   785  	for _, chart := range *charts {
   786  		chart.ID = fmt.Sprintf(chart.ID, zone)
   787  		chart.Labels = []module.Label{
   788  			{Key: "http_server_zone", Value: zone},
   789  		}
   790  		for _, dim := range chart.Dims {
   791  			dim.ID = fmt.Sprintf(dim.ID, zone)
   792  		}
   793  	}
   794  
   795  	if err := n.Charts().Add(*charts...); err != nil {
   796  		n.Warning(err)
   797  	}
   798  }
   799  
   800  func (n *NginxPlus) removeHTTPServerZoneCharts(zone string) {
   801  	px := fmt.Sprintf("http_server_zone_%s_", zone)
   802  	n.removeCharts(px)
   803  }
   804  
   805  func (n *NginxPlus) addHTTPLocationZoneCharts(zone string) {
   806  	charts := httpLocationZoneChartsTmpl.Copy()
   807  
   808  	for _, chart := range *charts {
   809  		chart.ID = fmt.Sprintf(chart.ID, zone)
   810  		chart.Labels = []module.Label{
   811  			{Key: "http_location_zone", Value: zone},
   812  		}
   813  		for _, dim := range chart.Dims {
   814  			dim.ID = fmt.Sprintf(dim.ID, zone)
   815  		}
   816  	}
   817  
   818  	if err := n.Charts().Add(*charts...); err != nil {
   819  		n.Warning(err)
   820  	}
   821  }
   822  
   823  func (n *NginxPlus) removeHTTPLocationZoneCharts(zone string) {
   824  	px := fmt.Sprintf("http_location_zone_%s_", zone)
   825  	n.removeCharts(px)
   826  }
   827  
   828  func (n *NginxPlus) addHTTPUpstreamCharts(name, zone string) {
   829  	charts := httpUpstreamChartsTmpl.Copy()
   830  
   831  	for _, chart := range *charts {
   832  		chart.ID = fmt.Sprintf(chart.ID, name, zone)
   833  		chart.Labels = []module.Label{
   834  			{Key: "http_upstream_name", Value: name},
   835  			{Key: "http_upstream_zone", Value: zone},
   836  		}
   837  		for _, dim := range chart.Dims {
   838  			dim.ID = fmt.Sprintf(dim.ID, name, zone)
   839  		}
   840  	}
   841  
   842  	if err := n.Charts().Add(*charts...); err != nil {
   843  		n.Warning(err)
   844  	}
   845  }
   846  
   847  func (n *NginxPlus) removeHTTPUpstreamCharts(name, zone string) {
   848  	px := fmt.Sprintf("http_upstream_%s_zone_%s", name, zone)
   849  	n.removeCharts(px)
   850  }
   851  
   852  func (n *NginxPlus) addHTTPUpstreamServerCharts(name, serverAddr, serverName, zone string) {
   853  	charts := httpUpstreamServerChartsTmpl.Copy()
   854  
   855  	for _, chart := range *charts {
   856  		chart.ID = fmt.Sprintf(chart.ID, name, serverAddr, zone)
   857  		chart.Labels = []module.Label{
   858  			{Key: "http_upstream_name", Value: name},
   859  			{Key: "http_upstream_zone", Value: zone},
   860  			{Key: "http_upstream_server_address", Value: serverAddr},
   861  			{Key: "http_upstream_server_name", Value: serverName},
   862  		}
   863  		for _, dim := range chart.Dims {
   864  			dim.ID = fmt.Sprintf(dim.ID, name, serverAddr, zone)
   865  		}
   866  	}
   867  
   868  	if err := n.Charts().Add(*charts...); err != nil {
   869  		n.Warning(err)
   870  	}
   871  }
   872  
   873  func (n *NginxPlus) removeHTTPUpstreamServerCharts(name, serverAddr, zone string) {
   874  	px := fmt.Sprintf("http_upstream_%s_server_%s_zone_%s_", name, zone, serverAddr)
   875  	n.removeCharts(px)
   876  }
   877  
   878  func (n *NginxPlus) addStreamServerZoneCharts(zone string) {
   879  	charts := streamServerZoneChartsTmpl.Copy()
   880  
   881  	for _, chart := range *charts {
   882  		chart.ID = fmt.Sprintf(chart.ID, zone)
   883  		chart.Labels = []module.Label{
   884  			{Key: "stream_server_zone", Value: zone},
   885  		}
   886  		for _, dim := range chart.Dims {
   887  			dim.ID = fmt.Sprintf(dim.ID, zone)
   888  		}
   889  	}
   890  
   891  	if err := n.Charts().Add(*charts...); err != nil {
   892  		n.Warning(err)
   893  	}
   894  }
   895  
   896  func (n *NginxPlus) removeStreamServerZoneCharts(zone string) {
   897  	px := fmt.Sprintf("stream_server_zone_%s_", zone)
   898  	n.removeCharts(px)
   899  }
   900  
   901  func (n *NginxPlus) addStreamUpstreamCharts(zone, name string) {
   902  	charts := streamUpstreamChartsTmpl.Copy()
   903  
   904  	for _, chart := range *charts {
   905  		chart.ID = fmt.Sprintf(chart.ID, zone, name)
   906  		chart.Labels = []module.Label{
   907  			{Key: "stream_upstream_zone", Value: name},
   908  			{Key: "stream_upstream_zone", Value: zone},
   909  		}
   910  		for _, dim := range chart.Dims {
   911  			dim.ID = fmt.Sprintf(dim.ID, zone, name)
   912  		}
   913  	}
   914  
   915  	if err := n.Charts().Add(*charts...); err != nil {
   916  		n.Warning(err)
   917  	}
   918  }
   919  
   920  func (n *NginxPlus) removeStreamUpstreamCharts(name, zone string) {
   921  	px := fmt.Sprintf("stream_upstream_%s_zone_%s_", name, zone)
   922  	n.removeCharts(px)
   923  }
   924  
   925  func (n *NginxPlus) addStreamUpstreamServerCharts(name, serverAddr, serverName, zone string) {
   926  	charts := streamUpstreamServerChartsTmpl.Copy()
   927  
   928  	for _, chart := range *charts {
   929  		chart.ID = fmt.Sprintf(chart.ID, name, serverAddr, zone)
   930  		chart.Labels = []module.Label{
   931  			{Key: "stream_upstream_name", Value: name},
   932  			{Key: "stream_upstream_zone", Value: zone},
   933  			{Key: "stream_upstream_server_address", Value: serverAddr},
   934  			{Key: "stream_upstream_server_name", Value: serverName},
   935  		}
   936  		for _, dim := range chart.Dims {
   937  			dim.ID = fmt.Sprintf(dim.ID, name, serverAddr, zone)
   938  		}
   939  	}
   940  
   941  	if err := n.Charts().Add(*charts...); err != nil {
   942  		n.Warning(err)
   943  	}
   944  }
   945  
   946  func (n *NginxPlus) removeStreamUpstreamServerCharts(name, serverAddr, zone string) {
   947  	px := fmt.Sprintf("stream_upstream_%s_server_%s_zone_%s", name, serverAddr, zone)
   948  	n.removeCharts(px)
   949  }
   950  
   951  func (n *NginxPlus) addResolverZoneCharts(zone string) {
   952  	charts := resolverZoneChartsTmpl.Copy()
   953  
   954  	for _, chart := range *charts {
   955  		chart.ID = fmt.Sprintf(chart.ID, zone)
   956  		chart.Labels = []module.Label{
   957  			{Key: "resolver_zone", Value: zone},
   958  		}
   959  		for _, dim := range chart.Dims {
   960  			dim.ID = fmt.Sprintf(dim.ID, zone)
   961  		}
   962  	}
   963  
   964  	if err := n.Charts().Add(*charts...); err != nil {
   965  		n.Warning(err)
   966  	}
   967  }
   968  
   969  func (n *NginxPlus) removeResolverZoneCharts(zone string) {
   970  	px := fmt.Sprintf("resolver_zone_%s_", zone)
   971  	n.removeCharts(px)
   972  }
   973  
   974  func (n *NginxPlus) removeCharts(prefix string) {
   975  	for _, chart := range *n.Charts() {
   976  		if strings.HasPrefix(chart.ID, prefix) {
   977  			chart.MarkRemove()
   978  			chart.MarkNotCreated()
   979  		}
   980  	}
   981  }