Skip to content

Commit 1c28eb8

Browse files
committed
implement azuretracing metrics
Signed-off-by: Markus Blaschke <[email protected]>
1 parent 1881c48 commit 1c28eb8

File tree

7 files changed

+89
-52
lines changed

7 files changed

+89
-52
lines changed

README.md

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Azure Janitor
2-
==============================
1+
# Azure Janitor
32

43
[![license](https://img.shields.io/github/license/webdevops/azure-janitor.svg)](https://github.com/webdevops/azure-janitor/blob/master/LICENSE)
54
[![DockerHub](https://img.shields.io/badge/DockerHub-webdevops%2Fazure--janitor-blue)](https://hub.docker.com/r/webdevops/azure-janitor/)
@@ -14,8 +13,7 @@ Janitor tasks:
1413
- ResourceGroup Deployment cleanup based on TTL and limit (count)
1514
- RoleAssignments cleanup based on RoleDefinitionIds and TTL
1615

17-
Usage
18-
-----
16+
## Usage
1917

2018
```
2119
Usage:
@@ -61,8 +59,7 @@ Help Options:
6159

6260
for Azure API authentication (using ENV vars) see https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication
6361

64-
Azure tag
65-
---------
62+
## Azure tag
6663

6764
By default the Azure Janitor is using `ttl` as tag and sets the expiry timestamp to `ttl_expiry`.
6865
Based on timestamp in `ttl_expiry` it will trigger the cleanup of the corresponding resource if expired.
@@ -97,8 +94,7 @@ Supported relative timestamps
9794
- 1mo (1 month)
9895
- 1y (1 year)
9996

100-
RoleAssignments
101-
---------------
97+
## RoleAssignments
10298

10399
**General RoleAssignment TTL**
104100

@@ -154,8 +150,7 @@ RoleAssignment example with ttl in description:
154150
},
155151
```
156152

157-
ARM template usage
158-
------------------
153+
## ARM template usage
159154

160155
Using relative time (duration):
161156
```
@@ -233,8 +228,7 @@ Using absolute calculated time:
233228
234229
```
235230

236-
Metrics
237-
-------
231+
## Metrics
238232

239233
| Metric | Type | Description |
240234
|------------------------------------------------|--------------|---------------------------------------------------------------------------------------|
@@ -243,3 +237,22 @@ Metrics
243237
| `azurejanitor_roleassignment_ttl` | Gauge | List of Azure RoleAssignments with expiry timestamp as value |
244238
| `azurejanitor_resources_deleted` | Counter | Number of deleted resources (by resource type) |
245239
| `azurejanitor_errors` | Counter | Number of failed deleted resources (by resource type) |
240+
241+
### Azuretracing metrics
242+
243+
(with 22.2.0 and later)
244+
245+
Azuretracing metrics collects latency and latency from azure-sdk-for-go and creates metrics and is controllable using
246+
environment variables (eg. setting buckets, disabling metrics or disable autoreset).
247+
248+
| Metric | Description |
249+
|------------------------------------------|----------------------------------------------------------------------------------------|
250+
| `azurerm_api_ratelimit` | Azure ratelimit metrics (only on /metrics, resets after query due to limited validity) |
251+
| `azurerm_api_request_*` | Azure request count and latency as histogram |
252+
253+
| Environment variable | Example | Description |
254+
|------------------------------------------|----------------------------------|----------------------------------------------------------|
255+
| `METRIC_AZURERM_API_REQUEST_BUCKETS` | `1, 2.5, 5, 10, 30, 60, 90, 120` | Sets buckets for `azurerm_api_request` histogram metric |
256+
| `METRIC_AZURERM_API_REQUEST_DISABLE` | `false` | Disables `azurerm_api_request_*` metric |
257+
| `METRIC_AZURERM_API_RATELIMIT_DISABLE` | `false` | Disables `azurerm_api_ratelimit` metric |
258+
| `METRIC_AZURERM_API_RATELIMIT_AUTORESET` | `false` | Disables `azurerm_api_ratelimit` autoreset after fetch |

janitor/deployments.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ func (j *Janitor) runDeployments(ctx context.Context, subscription subscriptions
1515
contextLogger := log.WithField("task", "deployment")
1616

1717
client := resources.NewGroupsClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint, *subscription.SubscriptionID)
18-
client.Authorizer = j.Azure.Authorizer
18+
j.decorateAzureAutorest(&client.Client)
1919

2020
resourceTtl := prometheusCommon.NewMetricsList()
2121

2222
deploymentClient := resources.NewDeploymentsClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint, *subscription.SubscriptionID)
23-
deploymentClient.Authorizer = j.Azure.Authorizer
23+
j.decorateAzureAutorest(&deploymentClient.Client)
2424

2525
resourceType := "Microsoft.Resources/deployments"
2626

janitor/janitor.go

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
log "github.com/sirupsen/logrus"
1515
"github.com/webdevops/azure-janitor/config"
1616
prometheusCommon "github.com/webdevops/go-prometheus-common"
17+
"github.com/webdevops/go-prometheus-common/azuretracing"
1718
"strings"
1819
"sync"
1920
"time"
@@ -30,6 +31,8 @@ type (
3031
Conf config.Opts
3132
Azure JanitorAzureConfig
3233

34+
UserAgent string
35+
3336
Prometheus struct {
3437
MetricDuration *prometheus.GaugeVec
3538
MetricTtlResources *prometheus.GaugeVec
@@ -70,6 +73,41 @@ var (
7073
)
7174

7275
func (j *Janitor) Init() {
76+
j.initPrometheus()
77+
j.initAzure()
78+
}
79+
80+
func (j *Janitor) initAzure() {
81+
ctx := context.Background()
82+
j.Azure.Subscriptions = []subscriptions.Subscription{}
83+
84+
client := subscriptions.NewClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint)
85+
j.decorateAzureAutorest(&client.Client)
86+
87+
if len(j.Conf.Azure.Subscription) == 0 {
88+
// auto lookup subscriptions
89+
listResult, err := client.List(ctx)
90+
if err != nil {
91+
panic(err)
92+
}
93+
j.Azure.Subscriptions = listResult.Values()
94+
95+
if len(j.Azure.Subscriptions) == 0 {
96+
log.Panic("no Azure Subscriptions found via auto detection, does this ServicePrincipal have read permissions to the subcriptions?")
97+
}
98+
} else {
99+
// fixed subscription list
100+
for _, subId := range j.Conf.Azure.Subscription {
101+
result, err := client.Get(ctx, subId)
102+
if err != nil {
103+
panic(err)
104+
}
105+
j.Azure.Subscriptions = append(j.Azure.Subscriptions, result)
106+
}
107+
}
108+
}
109+
110+
func (j *Janitor) initPrometheus() {
73111
j.Prometheus.MetricDuration = prometheus.NewGaugeVec(
74112
prometheus.GaugeOpts{
75113
Name: "azurejanitor_duration",
@@ -237,7 +275,8 @@ func (j *Janitor) initAuzreApiVersions() {
237275

238276
// fetch location translation map
239277
locationClient := subscriptions.NewClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint)
240-
locationClient.Authorizer = j.Azure.Authorizer
278+
j.decorateAzureAutorest(&locationClient.Client)
279+
241280
locationResult, err := locationClient.ListLocations(ctx, subscriptionId, nil)
242281
if err != nil {
243282
panic(err)
@@ -252,7 +291,7 @@ func (j *Janitor) initAuzreApiVersions() {
252291

253292
// fetch providers
254293
providersClient := resources.NewProvidersClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint, *subscription.SubscriptionID)
255-
providersClient.Authorizer = j.Azure.Authorizer
294+
j.decorateAzureAutorest(&providersClient.Client)
256295

257296
result, err := providersClient.ListComplete(ctx, nil, "")
258297
if err != nil {
@@ -451,3 +490,12 @@ func (j *Janitor) checkExpiryDate(value string) (parsedTime *time.Time, expired
451490

452491
return
453492
}
493+
494+
func (j *Janitor) decorateAzureAutorest(client *autorest.Client) {
495+
client.Authorizer = j.Azure.Authorizer
496+
if err := client.AddToUserAgent(j.UserAgent); err != nil {
497+
log.Panic(err)
498+
}
499+
500+
azuretracing.DecoreAzureAutoRest(client)
501+
}

janitor/resourcegroups.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func (j *Janitor) runResourceGroups(ctx context.Context, subscription subscripti
1414
resourceType := "Microsoft.Resources/resourceGroups"
1515

1616
client := resources.NewGroupsClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint, *subscription.SubscriptionID)
17-
client.Authorizer = j.Azure.Authorizer
17+
j.decorateAzureAutorest(&client.Client)
1818

1919
resourceTtl := prometheusCommon.NewMetricsList()
2020

janitor/resources.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func (j *Janitor) runResources(ctx context.Context, subscription subscriptions.S
1414
contextLogger := log.WithField("task", "resource")
1515

1616
client := resources.NewClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint, *subscription.SubscriptionID)
17-
client.Authorizer = j.Azure.Authorizer
17+
j.decorateAzureAutorest(&client.Client)
1818

1919
resourceTtl := prometheusCommon.NewMetricsList()
2020

janitor/roleassignments.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func (j *Janitor) runRoleAssignments(ctx context.Context, subscription subscript
1818
resourceType := "Microsoft.Authorization/roleAssignments"
1919

2020
client := authorization.NewRoleAssignmentsClientWithBaseURI(j.Azure.Environment.ResourceManagerEndpoint, *subscription.SubscriptionID)
21-
client.Authorizer = j.Azure.Authorizer
21+
j.decorateAzureAutorest(&client.Client)
2222

2323
result, err := client.ListComplete(ctx, filter, "")
2424
if err != nil {

main.go

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"context"
54
"fmt"
65
"github.com/Azure/azure-sdk-for-go/profiles/latest/resources/mgmt/subscriptions"
76
"github.com/Azure/go-autorest/autorest"
@@ -12,6 +11,7 @@ import (
1211
log "github.com/sirupsen/logrus"
1312
"github.com/webdevops/azure-janitor/config"
1413
"github.com/webdevops/azure-janitor/janitor"
14+
"github.com/webdevops/go-prometheus-common/azuretracing"
1515
"net/http"
1616
"os"
1717
"path"
@@ -22,6 +22,8 @@ import (
2222

2323
const (
2424
Author = "webdevops.io"
25+
26+
UserAgent = "azure-janitor/"
2527
)
2628

2729
var (
@@ -49,11 +51,11 @@ func main() {
4951

5052
log.Infof("init Janitor")
5153
j := janitor.Janitor{
52-
Conf: opts,
54+
Conf: opts,
55+
UserAgent: UserAgent + gitTag,
5356
Azure: janitor.JanitorAzureConfig{
54-
Authorizer: azureAuthorizer,
55-
Subscriptions: azureSubscriptions,
56-
Environment: azureEnvironment,
57+
Authorizer: azureAuthorizer,
58+
Environment: azureEnvironment,
5759
},
5860
}
5961
j.Init()
@@ -177,7 +179,6 @@ func checkForDeprecations() {
177179
// Init and build Azure authorzier
178180
func initAzureConnection() {
179181
var err error
180-
ctx := context.Background()
181182

182183
// get environment
183184
azureEnvironment, err = azure.EnvironmentFromName(*opts.Azure.Environment)
@@ -190,32 +191,6 @@ func initAzureConnection() {
190191
if err != nil {
191192
panic(err)
192193
}
193-
194-
subscriptionsClient := subscriptions.NewClientWithBaseURI(azureEnvironment.ResourceManagerEndpoint)
195-
subscriptionsClient.Authorizer = azureAuthorizer
196-
197-
if len(opts.Azure.Subscription) == 0 {
198-
// auto lookup subscriptions
199-
listResult, err := subscriptionsClient.List(ctx)
200-
if err != nil {
201-
panic(err)
202-
}
203-
azureSubscriptions = listResult.Values()
204-
205-
if len(azureSubscriptions) == 0 {
206-
log.Panic("no Azure Subscriptions found via auto detection, does this ServicePrincipal have read permissions to the subcriptions?")
207-
}
208-
} else {
209-
// fixed subscription list
210-
azureSubscriptions = []subscriptions.Subscription{}
211-
for _, subId := range opts.Azure.Subscription {
212-
result, err := subscriptionsClient.Get(ctx, subId)
213-
if err != nil {
214-
panic(err)
215-
}
216-
azureSubscriptions = append(azureSubscriptions, result)
217-
}
218-
}
219194
}
220195

221196
// start and handle prometheus handler
@@ -227,6 +202,7 @@ func startHttpServer() {
227202
}
228203
})
229204

230-
http.Handle("/metrics", promhttp.Handler())
205+
http.Handle("/metrics", azuretracing.RegisterAzureMetricAutoClean(promhttp.Handler()))
206+
231207
log.Fatal(http.ListenAndServe(opts.ServerBind, nil))
232208
}

0 commit comments

Comments
 (0)