-
Notifications
You must be signed in to change notification settings - Fork 167
/
monitor.go
192 lines (166 loc) · 6.22 KB
/
monitor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package cmd
import (
"context"
"errors"
"fmt"
"github.com/azure/azure-dev/cli/azd/cmd/actions"
"github.com/azure/azure-dev/cli/azd/internal"
"github.com/azure/azure-dev/cli/azd/pkg/account"
"github.com/azure/azure-dev/cli/azd/pkg/alpha"
"github.com/azure/azure-dev/cli/azd/pkg/apphost"
"github.com/azure/azure-dev/cli/azd/pkg/azapi"
"github.com/azure/azure-dev/cli/azd/pkg/azure"
"github.com/azure/azure-dev/cli/azd/pkg/cloud"
"github.com/azure/azure-dev/cli/azd/pkg/environment"
"github.com/azure/azure-dev/cli/azd/pkg/environment/azdcontext"
"github.com/azure/azure-dev/cli/azd/pkg/infra"
"github.com/azure/azure-dev/cli/azd/pkg/input"
"github.com/azure/azure-dev/cli/azd/pkg/output"
"github.com/azure/azure-dev/cli/azd/pkg/tools/azcli"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type monitorFlags struct {
monitorLive bool
monitorLogs bool
monitorOverview bool
global *internal.GlobalCommandOptions
internal.EnvFlag
}
func (m *monitorFlags) Bind(local *pflag.FlagSet, global *internal.GlobalCommandOptions) {
local.BoolVar(
&m.monitorLive,
"live",
false,
"Open a browser to Application Insights Live Metrics. Live Metrics is currently not supported for Python apps.",
)
local.BoolVar(&m.monitorLogs, "logs", false, "Open a browser to Application Insights Logs.")
local.BoolVar(&m.monitorOverview, "overview", false, "Open a browser to Application Insights Overview Dashboard.")
m.EnvFlag.Bind(local, global)
m.global = global
}
func newMonitorFlags(cmd *cobra.Command, global *internal.GlobalCommandOptions) *monitorFlags {
flags := &monitorFlags{}
flags.Bind(cmd.Flags(), global)
return flags
}
func newMonitorCmd() *cobra.Command {
return &cobra.Command{
Use: "monitor",
Short: fmt.Sprintf("Monitor a deployed application. %s", output.WithWarningFormat("(Beta)")),
}
}
type monitorAction struct {
azdCtx *azdcontext.AzdContext
env *environment.Environment
subResolver account.SubscriptionTenantResolver
azCli azcli.AzCli
deploymentOperations azapi.DeploymentOperations
console input.Console
flags *monitorFlags
portalUrlBase string
alphaFeaturesManager *alpha.FeatureManager
}
func newMonitorAction(
azdCtx *azdcontext.AzdContext,
env *environment.Environment,
subResolver account.SubscriptionTenantResolver,
azCli azcli.AzCli,
deploymentOperations azapi.DeploymentOperations,
console input.Console,
flags *monitorFlags,
portalUrlBase cloud.PortalUrlBase,
alphaFeatureManager *alpha.FeatureManager,
) actions.Action {
return &monitorAction{
azdCtx: azdCtx,
env: env,
azCli: azCli,
deploymentOperations: deploymentOperations,
console: console,
flags: flags,
subResolver: subResolver,
portalUrlBase: string(portalUrlBase),
alphaFeaturesManager: alphaFeatureManager,
}
}
func (m *monitorAction) Run(ctx context.Context) (*actions.ActionResult, error) {
if !m.flags.monitorLive && !m.flags.monitorLogs && !m.flags.monitorOverview {
m.flags.monitorOverview = true
}
if m.env.GetSubscriptionId() == "" {
return nil, errors.New(
"infrastructure has not been provisioned. Run `azd provision`",
)
}
aspireDashboard := apphost.AspireDashboardUrl(ctx, m.env, m.alphaFeaturesManager)
if aspireDashboard != nil {
openWithDefaultBrowser(ctx, m.console, aspireDashboard.Link)
return nil, nil
}
resourceManager := infra.NewAzureResourceManager(m.azCli, m.deploymentOperations)
resourceGroups, err := resourceManager.GetResourceGroupsForEnvironment(
ctx, m.env.GetSubscriptionId(), m.env.Name())
if err != nil {
return nil, fmt.Errorf("discovering resource groups from deployment: %w", err)
}
var insightsResources []azcli.AzCliResource
var portalResources []azcli.AzCliResource
for _, resourceGroup := range resourceGroups {
resources, err := m.azCli.ListResourceGroupResources(
ctx, azure.SubscriptionFromRID(resourceGroup.Id), resourceGroup.Name, nil)
if err != nil {
return nil, fmt.Errorf("listing resources: %w", err)
}
for _, resource := range resources {
switch resource.Type {
case string(infra.AzureResourceTypePortalDashboard):
portalResources = append(portalResources, resource)
case string(infra.AzureResourceTypeAppInsightComponent):
insightsResources = append(insightsResources, resource)
}
}
}
if len(insightsResources) == 0 && (m.flags.monitorLive || m.flags.monitorLogs) {
return nil, fmt.Errorf("application does not contain an Application Insights resource")
}
if len(portalResources) == 0 && m.flags.monitorOverview {
return nil, fmt.Errorf("application does not contain an Application Insights dashboard")
}
tenantId, err := m.subResolver.LookupTenant(ctx, m.env.GetSubscriptionId())
if err != nil {
return nil, err
}
for _, insightsResource := range insightsResources {
if m.flags.monitorLive {
openWithDefaultBrowser(ctx, m.console,
fmt.Sprintf("%s/#@%s/resource%s/quickPulse", m.portalUrlBase, tenantId, insightsResource.Id))
}
if m.flags.monitorLogs {
openWithDefaultBrowser(ctx, m.console,
fmt.Sprintf("%s/#@%s/resource%s/logs", m.portalUrlBase, tenantId, insightsResource.Id))
}
}
for _, portalResource := range portalResources {
if m.flags.monitorOverview {
openWithDefaultBrowser(ctx, m.console,
fmt.Sprintf("%s/#@%s/dashboard/arm%s", m.portalUrlBase, tenantId, portalResource.Id))
}
}
return nil, nil
}
func getCmdMonitorHelpDescription(*cobra.Command) string {
return generateCmdHelpDescription(
fmt.Sprintf("Monitor a deployed application %s. For more information, go to: %s.",
output.WithWarningFormat("(Beta)"),
output.WithLinkFormat("https://aka.ms/azure-dev/monitor")), nil)
}
func getCmdMonitorHelpFooter(c *cobra.Command) string {
return generateCmdHelpSamplesBlock(map[string]string{
"Open Application Insights Overview Dashboard.": output.WithHighLightFormat("azd monitor --overview"),
"Open Application Insights Live Metrics.": output.WithHighLightFormat("azd monitor --live"),
"Open Application Insights Logs.": output.WithHighLightFormat("azd monitor --logs"),
})
}