or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cluster-management.mddata-connections.mddatabase-management.mdindex.mdmonitoring-operations.mdscripts-extensions.mdsecurity-management.md

monitoring-operations.mddocs/

0

# Monitoring and Operations

1

2

Monitoring capabilities including operation results tracking, SKU information retrieval, and management of attached database configurations for database sharing scenarios. This enables operational oversight and resource planning for Kusto deployments.

3

4

## Capabilities

5

6

### Operations Discovery

7

8

Operations to discover available management operations and their capabilities.

9

10

```python { .api }

11

def list(**kwargs) -> Iterable[Operation]:

12

"""

13

List available operations for the Kusto resource provider.

14

15

Returns:

16

Iterable of Operation objects describing available operations

17

"""

18

```

19

20

### Operation Results Tracking

21

22

Operations to track the status and results of long-running operations.

23

24

```python { .api }

25

def get(

26

location: str,

27

operation_id: str,

28

**kwargs

29

) -> OperationResult:

30

"""

31

Get the result of a long-running operation.

32

33

Parameters:

34

- location: Azure region where the operation was initiated

35

- operation_id: Unique identifier of the operation

36

37

Returns:

38

OperationResult with operation status and details

39

"""

40

```

41

42

### Location-Based Operation Results

43

44

Operations to retrieve operation results based on location for geographically distributed operations.

45

46

```python { .api }

47

def get(

48

location: str,

49

operation_id: str,

50

**kwargs

51

) -> OperationResult:

52

"""

53

Get the result of a location-based long-running operation.

54

55

Parameters:

56

- location: Azure region where the operation was initiated

57

- operation_id: Unique identifier of the operation

58

59

Returns:

60

OperationResult with operation status and details

61

"""

62

```

63

64

### SKU Information Retrieval

65

66

Operations to discover available SKUs and their capabilities for capacity planning.

67

68

```python { .api }

69

def list(**kwargs) -> Iterable[SkuDescription]:

70

"""

71

List available SKUs for Kusto clusters.

72

73

Returns:

74

Iterable of SkuDescription objects with SKU details and availability

75

"""

76

```

77

78

### Attached Database Configurations

79

80

Management of attached database configurations that enable database sharing between clusters.

81

82

```python { .api }

83

def get(

84

resource_group_name: str,

85

cluster_name: str,

86

attached_database_configuration_name: str,

87

**kwargs

88

) -> AttachedDatabaseConfiguration:

89

"""

90

Get an attached database configuration.

91

92

Parameters:

93

- resource_group_name: Name of the resource group

94

- cluster_name: Name of the Kusto cluster

95

- attached_database_configuration_name: Name of the configuration

96

97

Returns:

98

AttachedDatabaseConfiguration object

99

"""

100

101

def begin_create_or_update(

102

resource_group_name: str,

103

cluster_name: str,

104

attached_database_configuration_name: str,

105

parameters: AttachedDatabaseConfiguration,

106

**kwargs

107

) -> LROPoller[AttachedDatabaseConfiguration]:

108

"""

109

Create or update an attached database configuration.

110

111

Parameters:

112

- resource_group_name: Name of the resource group

113

- cluster_name: Name of the Kusto cluster

114

- attached_database_configuration_name: Name of the configuration

115

- parameters: AttachedDatabaseConfiguration with settings

116

117

Returns:

118

LROPoller for the long-running operation returning AttachedDatabaseConfiguration

119

"""

120

121

def begin_delete(

122

resource_group_name: str,

123

cluster_name: str,

124

attached_database_configuration_name: str,

125

**kwargs

126

) -> LROPoller[None]:

127

"""

128

Delete an attached database configuration.

129

130

Parameters:

131

- resource_group_name: Name of the resource group

132

- cluster_name: Name of the Kusto cluster

133

- attached_database_configuration_name: Name of the configuration

134

135

Returns:

136

LROPoller for the long-running delete operation

137

"""

138

139

def list_by_cluster(

140

resource_group_name: str,

141

cluster_name: str,

142

**kwargs

143

) -> Iterable[AttachedDatabaseConfiguration]:

144

"""

145

List attached database configurations for a cluster.

146

147

Parameters:

148

- resource_group_name: Name of the resource group

149

- cluster_name: Name of the Kusto cluster

150

151

Returns:

152

Iterable of AttachedDatabaseConfiguration objects

153

"""

154

155

def check_name_availability(

156

resource_group_name: str,

157

cluster_name: str,

158

resource_name: AttachedDatabaseConfigurationsCheckNameRequest,

159

**kwargs

160

) -> CheckNameResult:

161

"""

162

Check if an attached database configuration name is available.

163

164

Parameters:

165

- resource_group_name: Name of the resource group

166

- cluster_name: Name of the Kusto cluster

167

- resource_name: CheckNameRequest with name to validate

168

169

Returns:

170

CheckNameResult indicating availability

171

"""

172

```

173

174

## Usage Examples

175

176

### Monitoring Long-Running Operations

177

178

```python

179

# Start a long-running operation (e.g., cluster creation)

180

poller = client.clusters.begin_create_or_update(

181

resource_group_name="my-resource-group",

182

cluster_name="my-cluster",

183

parameters=cluster_params

184

)

185

186

# Get operation details

187

operation_id = poller._operation.resource().name

188

location = "East US"

189

190

# Check operation status

191

operation_result = client.operations_results.get(

192

location=location,

193

operation_id=operation_id

194

)

195

196

print(f"Operation Status: {operation_result.status}")

197

print(f"Operation Name: {operation_result.name}")

198

199

if operation_result.error:

200

print(f"Operation Error: {operation_result.error.message}")

201

```

202

203

### Listing Available SKUs

204

205

```python

206

# Get all available SKUs

207

available_skus = list(client.skus.list())

208

209

print("Available Kusto Cluster SKUs:")

210

for sku in available_skus:

211

print(f"- {sku.name}: {sku.tier}")

212

print(f" Locations: {', '.join(sku.locations)}")

213

print(f" Capabilities: {len(sku.capabilities)} features")

214

215

for capability in sku.capabilities:

216

print(f" {capability.name}: {capability.value}")

217

print()

218

```

219

220

### Creating an Attached Database Configuration

221

222

```python

223

from azure.mgmt.kusto.models import (

224

AttachedDatabaseConfiguration,

225

DefaultPrincipalsModificationKind,

226

TableLevelSharingProperties

227

)

228

229

# Configure table-level sharing

230

table_sharing = TableLevelSharingProperties(

231

tables_to_include=["Table1", "Table2", "Table3"],

232

tables_to_exclude=[],

233

external_tables_to_include=["ExternalTable1"],

234

external_tables_to_exclude=[],

235

materialized_views_to_include=["MaterializedView1"],

236

materialized_views_to_exclude=[],

237

functions_to_include=["Function1", "Function2"],

238

functions_to_exclude=[]

239

)

240

241

# Create attached database configuration

242

attached_config = AttachedDatabaseConfiguration(

243

location="East US",

244

database_name="SharedDatabase",

245

cluster_resource_id="/subscriptions/sub-id/resourceGroups/source-rg/providers/Microsoft.Kusto/clusters/source-cluster",

246

default_principals_modification_kind=DefaultPrincipalsModificationKind.UNION,

247

table_level_sharing_properties=table_sharing,

248

database_name_prefix="Shared_"

249

)

250

251

# Create the configuration

252

poller = client.attached_database_configurations.begin_create_or_update(

253

resource_group_name="my-resource-group",

254

cluster_name="my-follower-cluster",

255

attached_database_configuration_name="shared-database-config",

256

parameters=attached_config

257

)

258

259

config = poller.result()

260

print(f"Attached database configuration created: {config.name}")

261

print(f"Attached databases: {', '.join(config.attached_database_names)}")

262

```

263

264

### Discovering Available Operations

265

266

```python

267

# List all available operations

268

operations = list(client.operations.list())

269

270

print("Available Kusto Management Operations:")

271

for operation in operations:

272

print(f"- {operation.name}")

273

print(f" Display Name: {operation.display.operation}")

274

print(f" Description: {operation.display.description}")

275

print(f" Provider: {operation.display.provider}")

276

print(f" Resource: {operation.display.resource}")

277

print()

278

```

279

280

### Monitoring Cluster Health

281

282

```python

283

# Get cluster details for health monitoring

284

cluster = client.clusters.get(

285

resource_group_name="my-resource-group",

286

cluster_name="my-cluster"

287

)

288

289

print(f"Cluster Health Status:")

290

print(f"- Name: {cluster.name}")

291

print(f"- State: {cluster.state}")

292

print(f"- Provisioning State: {cluster.provisioning_state}")

293

print(f"- URI: {cluster.uri}")

294

print(f"- Data Ingestion URI: {cluster.data_ingestion_uri}")

295

print(f"- SKU: {cluster.sku.name} ({cluster.sku.capacity} instances)")

296

297

# List follower databases

298

followers = list(client.clusters.list_follower_databases(

299

resource_group_name="my-resource-group",

300

cluster_name="my-cluster"

301

))

302

303

print(f"- Follower Databases: {len(followers)}")

304

for follower in followers:

305

print(f" - {follower.cluster_resource_id} -> {follower.database_name}")

306

```

307

308

## Key Types

309

310

```python { .api }

311

class Operation:

312

"""Represents an available management operation."""

313

name: str # Operation name

314

is_data_action: bool # Whether operation is a data action

315

display: OperationDisplay # Display information

316

origin: str # Operation origin

317

properties: dict # Additional properties

318

319

class OperationDisplay:

320

"""Display information for an operation."""

321

provider: str # Resource provider name

322

resource: str # Resource type

323

operation: str # Operation name

324

description: str # Operation description

325

326

class OperationResult:

327

"""Result of a long-running operation."""

328

# Read-only properties

329

id: str # Operation ID

330

name: str # Operation name

331

status: str # Operation status

332

start_time: datetime # Operation start time

333

end_time: datetime # Operation end time

334

percent_complete: float # Completion percentage

335

properties: dict # Operation-specific properties

336

error: ErrorDetail # Error details if operation failed

337

338

class SkuDescription:

339

"""Description of an available SKU."""

340

resource_type: str # Resource type

341

name: str # SKU name

342

tier: str # SKU tier

343

locations: List[str] # Available locations

344

location_info: List[SkuLocationInfoItem] # Location-specific information

345

capabilities: List[ResourceSkuCapabilities] # SKU capabilities

346

restrictions: List[dict] # SKU restrictions

347

348

class ResourceSkuCapabilities:

349

"""Capabilities of a resource SKU."""

350

name: str # Capability name

351

value: str # Capability value

352

353

class SkuLocationInfoItem:

354

"""Location-specific SKU information."""

355

location: str # Azure region

356

zones: List[str] # Available zones

357

zone_details: List[ResourceSkuZoneDetails] # Zone-specific details

358

359

class AttachedDatabaseConfiguration:

360

"""Configuration for sharing databases between clusters."""

361

# Read-only properties

362

id: str # Resource ID

363

name: str # Configuration name

364

type: str # Resource type

365

provisioning_state: ProvisioningState # Provisioning state

366

attached_database_names: List[str] # Names of attached databases

367

368

# Configuration properties

369

location: str # Azure region

370

database_name: str # Database name pattern (* for all)

371

cluster_resource_id: str # Source cluster resource ID

372

default_principals_modification_kind: DefaultPrincipalsModificationKind # Principal handling

373

table_level_sharing_properties: TableLevelSharingProperties # Table sharing config

374

database_name_override: str # Override database name

375

database_name_prefix: str # Prefix for database names

376

377

class TableLevelSharingProperties:

378

"""Table-level sharing configuration."""

379

tables_to_include: List[str] # Tables to include

380

tables_to_exclude: List[str] # Tables to exclude

381

external_tables_to_include: List[str] # External tables to include

382

external_tables_to_exclude: List[str] # External tables to exclude

383

materialized_views_to_include: List[str] # Materialized views to include

384

materialized_views_to_exclude: List[str] # Materialized views to exclude

385

functions_to_include: List[str] # Functions to include

386

functions_to_exclude: List[str] # Functions to exclude

387

388

class AttachedDatabaseConfigurationsCheckNameRequest:

389

"""Request to check attached database configuration name availability."""

390

name: str # Name to check

391

type: str # Resource type

392

393

from enum import Enum

394

395

class DefaultPrincipalsModificationKind(str, Enum):

396

"""Default principals modification behavior."""

397

UNION = "Union" # Combine source and target principals

398

REPLACE = "Replace" # Replace target principals with source

399

NONE = "None" # No principal modification

400

```

401

402

## Error Handling and Monitoring Patterns

403

404

### Monitoring Operation Progress

405

406

```python

407

from azure.core.exceptions import HttpResponseError

408

import time

409

410

def monitor_long_running_operation(poller, operation_name):

411

"""Monitor a long-running operation with progress reporting."""

412

print(f"Starting {operation_name}...")

413

414

try:

415

while not poller.done():

416

print(f"Operation in progress... Status: {poller.status()}")

417

time.sleep(30) # Wait 30 seconds between checks

418

419

result = poller.result()

420

print(f"{operation_name} completed successfully")

421

return result

422

423

except HttpResponseError as e:

424

print(f"{operation_name} failed: {e.message}")

425

426

# Get detailed error information

427

if hasattr(e, 'error') and e.error:

428

print(f"Error Code: {e.error.code}")

429

print(f"Error Details: {e.error.message}")

430

431

if hasattr(e.error, 'details') and e.error.details:

432

for detail in e.error.details:

433

print(f"Additional Info: {detail.code} - {detail.message}")

434

435

raise

436

437

# Usage example

438

poller = client.clusters.begin_create_or_update(

439

resource_group_name="my-resource-group",

440

cluster_name="my-cluster",

441

parameters=cluster_params

442

)

443

444

cluster = monitor_long_running_operation(poller, "Cluster Creation")

445

```

446

447

### Health Check Implementation

448

449

```python

450

def perform_cluster_health_check(client, resource_group_name, cluster_name):

451

"""Perform comprehensive health check on a Kusto cluster."""

452

health_status = {

453

"cluster_accessible": False,

454

"provisioning_state": None,

455

"cluster_state": None,

456

"databases": [],

457

"data_connections": [],

458

"issues": []

459

}

460

461

try:

462

# Check cluster status

463

cluster = client.clusters.get(

464

resource_group_name=resource_group_name,

465

cluster_name=cluster_name

466

)

467

468

health_status["cluster_accessible"] = True

469

health_status["provisioning_state"] = cluster.provisioning_state

470

health_status["cluster_state"] = cluster.state

471

472

# Check if cluster is in a healthy state

473

if cluster.state != "Running":

474

health_status["issues"].append(f"Cluster state is {cluster.state}, expected Running")

475

476

if cluster.provisioning_state != "Succeeded":

477

health_status["issues"].append(f"Provisioning state is {cluster.provisioning_state}, expected Succeeded")

478

479

# Check databases

480

databases = list(client.databases.list_by_cluster(

481

resource_group_name=resource_group_name,

482

cluster_name=cluster_name

483

))

484

485

for db in databases:

486

db_status = {

487

"name": db.name,

488

"provisioning_state": db.provisioning_state,

489

"healthy": db.provisioning_state == "Succeeded"

490

}

491

health_status["databases"].append(db_status)

492

493

if not db_status["healthy"]:

494

health_status["issues"].append(f"Database {db.name} provisioning state is {db.provisioning_state}")

495

496

# Check data connections for each database

497

try:

498

connections = list(client.data_connections.list_by_database(

499

resource_group_name=resource_group_name,

500

cluster_name=cluster_name,

501

database_name=db.name

502

))

503

504

for conn in connections:

505

conn_status = {

506

"database": db.name,

507

"name": conn.name,

508

"kind": conn.kind,

509

"provisioning_state": conn.provisioning_state,

510

"healthy": conn.provisioning_state == "Succeeded"

511

}

512

health_status["data_connections"].append(conn_status)

513

514

if not conn_status["healthy"]:

515

health_status["issues"].append(f"Data connection {conn.name} in {db.name} provisioning state is {conn.provisioning_state}")

516

517

except HttpResponseError as e:

518

health_status["issues"].append(f"Failed to check data connections for {db.name}: {e.message}")

519

520

except HttpResponseError as e:

521

health_status["issues"].append(f"Failed to access cluster: {e.message}")

522

523

return health_status

524

525

# Usage example

526

health = perform_cluster_health_check(client, "my-resource-group", "my-cluster")

527

print(f"Cluster Health: {'HEALTHY' if not health['issues'] else 'ISSUES FOUND'}")

528

529

if health["issues"]:

530

print("Issues found:")

531

for issue in health["issues"]:

532

print(f"- {issue}")

533

```