Criar uma aplicação para executar comandos de gestão
Artigo 12/08/2023
3 contribuidores
Comentários
Neste artigo
Neste artigo, vai aprender a:
Pré-requisitos
Configure o seu ambiente de desenvolvimento para utilizar a biblioteca de cliente Kusto.
Executar um comando de gestão e processar os resultados
No seu IDE ou editor de texto preferido, crie um projeto ou ficheiro denominado comandos de gestão com a convenção adequada para o seu idioma preferido. Em seguida, adicione o seguinte código:
Crie uma aplicação cliente que ligue o cluster. Substitua o <your_cluster_uri>
marcador de posição pelo nome do cluster.
Nota
Para comandos de gestão, irá utilizar o método de fábrica de CreateCslAdminProvider
cliente.
using Kusto.Data;
using Kusto.Data.Net.Client;
namespace ManagementCommands {
class ManagementCommands {
static void Main(string[] args) {
var clusterUri = "<your_cluster_uri>";
var kcsb = new KustoConnectionStringBuilder(clusterUri)
.WithAadUserPromptAuthentication();
using (var kustoClient = KustoClientFactory.CreateCslAdminProvider(kcsb)) {
}
}
}
}
from azure.kusto.data import KustoClient, KustoConnectionStringBuilder
def main():
cluster_uri = "<your_cluster_uri>"
kcsb = KustoConnectionStringBuilder.with_interactive_login(cluster_uri)
with KustoClient(kcsb) as kusto_client:
if __name__ == "__main__":
main()
import { Client as KustoClient, KustoConnectionStringBuilder } from "azure-kusto-data/";
import { InteractiveBrowserCredentialInBrowserOptions } from "@azure/identity";
async function main() {
const clusterUri = "<your_cluster_uri>";
const authOptions = {
clientId: "5e39af3b-ba50-4255-b547-81abfb507c58",
redirectUri: "http://localhost:5173",
} as InteractiveBrowserCredentialInBrowserOptions;
const kcsb = KustoConnectionStringBuilder.withUserPrompt(clusterUri, authOptions);
const kustoClient = new KustoClient(kcsb);
}
main();
Nota
Para Node.js aplicações, utilize InteractiveBrowserCredentialNodeOptions
em vez de InteractiveBrowserCredentialInBrowserOptions
.
import com.microsoft.azure.kusto.data.Client;
import com.microsoft.azure.kusto.data.ClientFactory;
import com.microsoft.azure.kusto.data.KustoOperationResult;
import com.microsoft.azure.kusto.data.KustoResultSetTable;
import com.microsoft.azure.kusto.data.KustoResultColumn;
import com.microsoft.azure.kusto.data.auth.ConnectionStringBuilder;
public class ManagementCommands {
public static void main(String[] args) throws Exception {
try {
String clusterUri = "<your_cluster_uri>";
ConnectionStringBuilder kcsb = ConnectionStringBuilder.createWithUserPrompt(clusterUri);
try (Client kustoClient = ClientFactory.createClient(kcsb)) {
}
}
}
}
Defina uma função que imprima o comando que está a ser executado e as respetivas tabelas resultantes. Esta função descompacta os nomes das colunas nas tabelas de resultados e imprime cada par nome-valor numa nova linha.
static void PrintResultsAsValueList(string command, IDataReader response) {
while (response.Read()) {
Console.WriteLine("\n{0}\n", new String('-', 20));
Console.WriteLine("Command: {0}", command);
Console.WriteLine("Result:");
for (int i = 0; i < response.FieldCount; i++) {
Console.WriteLine("\t{0} - {1}", response.GetName(i), response.IsDBNull(i) ? "None" : response.GetString(i));
}
}
}
def print_result_as_value_list(command, response):
# create a list of columns
cols = (col.column_name for col in response.primary_results[0].columns)
print("\n" + "-" * 20 + "\n")
print("Command: " + command)
# print the values for each row
for row in response.primary_results[0]:
print("Result:")
for col in cols:
print("\t", col, "-", row[col])
function printResultsAsValueList(command: string, response: KustoResponseDataSet) {
// create a list of columns
const cols = response.primaryResults[0].columns;
console.log("\n" + "-".repeat(20) + "\n")
console.log("Command: " + command)
// print the values for each row
for (const row of response.primaryResults[0].rows()) {
console.log("Result:")
for (col of cols)
console.log("\t", col.name, "-", row.getValueAt(col.ordinal) ? row.getValueAt(col.ordinal).toString() : "None")
}
}
public static void printResultsAsValueList(String command, KustoResultSetTable results) {
while (results.next()) {
System.out.println("\n" + "-".repeat(20) + "\n");
System.out.println("Command: " + command);
System.out.println("Result:");
KustoResultColumn[] columns = results.getColumns();
for (int i = 0; i < columns.length; i++) {
System.out.println("\t" + columns[i].getColumnName() + " - " + (results.getObject(i) == null ? "None" : results.getString(i)));
}
}
}
Defina o comando a executar. O comando cria uma tabela denominada MyStormEvents e define o esquema da tabela como uma lista de nomes e tipos de coluna. Substitua o <your_database>
marcador de posição pelo nome da base de dados.
string database = "<your_database>";
string table = "MyStormEvents";
// Create a table named MyStormEvents
// The brackets contain a list of column Name:Type pairs that defines the table schema
string command = @$".create table {table}
(StartTime:datetime,
EndTime:datetime,
State:string,
DamageProperty:int,
DamageCrops:int,
Source:string,
StormSummary:dynamic)";
database = "<your_database>"
table = "MyStormEvents"
# Create a table named MyStormEvents
# The brackets contain a list of column Name:Type pairs that defines the table schema
command = ".create table " + table + " " \
"(StartTime:datetime," \
" EndTime:datetime," \
" State:string," \
" DamageProperty:int," \
" DamageCrops:int," \
" Source:string," \
" StormSummary:dynamic)"
const database = "<your_database>";
const table = "MyStormEvents";
// Create a table named MyStormEvents
// The brackets contain a list of column Name:Type pairs that defines the table schema
const command = `.create table ${table}
(StartTime:datetime,
EndTime:datetime,
State:string,
DamageProperty:int,
Source:string,
StormSummary:dynamic)`;
String database = "<your_database>";
String table = "MyStormEvents";
// Create a table named MyStormEvents
// The brackets contain a list of column Name:Type pairs that defines the table schema
String command = ".create table " + table + " " +
"(StartTime:datetime," +
" EndTime:datetime," +
" State:string," +
" DamageProperty:int," +
" DamageCrops:int," +
" Source:string," +
" StormSummary:dynamic)";
Execute o comando e imprima o resultado com a função definida anteriormente.
Nota
Irá utilizar o ExecuteControlCommand
método para executar o comando .
using (var response = kustoClient.ExecuteControlCommand(database, command, null)) {
PrintResultsAsValueList(command, response);
}
Nota
Irá utilizar o execute_mgmt
método para executar o comando .
response = kusto_client.execute_mgmt(database, command)
print_result_as_value_list(command, response)
Nota
Irá utilizar o executeMgmt
método para executar o comando .
const response = await kustoClient.executeMgmt(database, command);
printResultsAsValueList(command, response)
KustoOperationResult response = kusto_client.execute(database, command);
printResultsAsValueList(command, response.getPrimaryResults());
O código completo deve ter o seguinte aspeto:
using Kusto.Data;
using Kusto.Data.Net.Client;
namespace ManagementCommands {
class ManagementCommands {
static void Main(string[] args) {
string clusterUri = "https://<your_cluster_uri>";
var kcsb = new KustoConnectionStringBuilder(clusterUri)
.WithAadUserPromptAuthentication();
using (var kustoClient = KustoClientFactory.CreateCslAdminProvider(kcsb)) {
string database = "<your_database>";
string table = "MyStormEvents";
// Create a table named MyStormEvents
// The brackets contain a list of column Name:Type pairs that defines the table schema
string command = @$".create table {table}
(StartTime:datetime,
EndTime:datetime,
State:string,
DamageProperty:int,
DamageCrops:int,
Source:string,
StormSummary:dynamic)";
using (var response = kustoClient.ExecuteControlCommand(database, command, null)) {
PrintResultsAsValueList(command, response);
}
}
}
static void PrintResultsAsValueList(string command, IDataReader response) {
while (response.Read()) {
Console.WriteLine("\n{0}\n", new String('-', 20));
Console.WriteLine("Command: {0}", command);
Console.WriteLine("Result:");
for (int i = 0; i < response.FieldCount; i++) {
Console.WriteLine("\t{0} - {1}", response.GetName(i), response.IsDBNull(i) ? "None" : response.GetString(i));
}
}
}
}
}
from azure.kusto.data import KustoClient, KustoConnectionStringBuilder
def main():
cluster_uri = "https://<your_cluster_uri>"
kcsb = KustoConnectionStringBuilder.with_interactive_login(cluster_uri)
with KustoClient(kcsb) as kusto_client:
database = "<your_database>"
table = "MyStormEvents"
# Create a table named MyStormEvents
# The brackets contain a list of column Name:Type pairs that defines the table schema
command = ".create table " + table + " " \
"(StartTime:datetime," \
" EndTime:datetime," \
" State:string," \
" DamageProperty:int," \
" DamageCrops:int," \
" Source:string," \
" StormSummary:dynamic)"
response = kusto_client.execute_mgmt(database, command)
print_result_as_value_list(command, response)
def print_result_as_value_list(command, response):
# create a list of columns
cols = (col.column_name for col in response.primary_results[0].columns)
print("\n" + "-" * 20 + "\n")
print("Command: " + command)
# print the values for each row
for row in response.primary_results[0]:
print("Result:")
for col in cols:
print("\t", col, "-", row[col])
if __name__ == "__main__":
main()
import { Client as KustoClient, KustoConnectionStringBuilder, KustoResponseDataSet } from "azure-kusto-data/";
import { InteractiveBrowserCredentialInBrowserOptions } from "@azure/identity";
async function main() {
const clusterUri = "<your_cluster_uri>";
const authOptions = {
clientId: "5e39af3b-ba50-4255-b547-81abfb507c58",
redirectUri: "http://localhost:5173",
} as InteractiveBrowserCredentialInBrowserOptions;
const kcsb = KustoConnectionStringBuilder.withUserPrompt(clusterUri, authOptions);
const kustoClient = new KustoClient(kcsb);
const database = "<your_database>";
const table = "MyStormEvents";
// Create a table named MyStormEvents
// The brackets contain a list of column Name:Type pairs that defines the table schema
const command = `.create table ${table}
(StartTime:datetime,
EndTime:datetime,
State:string,
DamageProperty:int,
Source:string,
StormSummary:dynamic)`;
const response = await kustoClient.executeMgmt(database, command);
printResultsAsValueList(command, response)
}
function printResultsAsValueList(command: string, response: KustoResponseDataSet) {
// create a list of columns
const cols = response.primaryResults[0].columns;
console.log("\n" + "-".repeat(20) + "\n")
console.log("Command: " + command)
// print the values for each row
for (const row of response.primaryResults[0].rows()) {
console.log("Result:")
for (const col of cols) {
console.log("\t", col.name, "-", row.getValueAt(col.ordinal) ? row.getValueAt(col.ordinal).toString() : "None")
}
}
}
main();
Nota
Para Node.js aplicações, utilize InteractiveBrowserCredentialNodeOptions
em vez de InteractiveBrowserCredentialInBrowserOptions
.
import com.microsoft.azure.kusto.data.Client;
import com.microsoft.azure.kusto.data.ClientFactory;
import com.microsoft.azure.kusto.data.KustoOperationResult;
import com.microsoft.azure.kusto.data.KustoResultSetTable;
import com.microsoft.azure.kusto.data.KustoResultColumn;
import com.microsoft.azure.kusto.data.auth.ConnectionStringBuilder;
public class ManagementCommands {
public static void main(String[] args) throws Exception {
try {
String clusterUri = "https://<your_cluster_uri>";
ConnectionStringBuilder kcsb = ConnectionStringBuilder.createWithUserPrompt(clusterUri);
try (Client kustoClient = ClientFactory.createClient(kcsb)) {
String database = "<your_database>";
String table = "MyStormEvents";
// Create a table named MyStormEvents
// The brackets contain a list of column Name:Type pairs that defines the table schema
String command = ".create table " + table + " " +
"(StartTime:datetime," +
" EndTime:datetime," +
" State:string," +
" DamageProperty:int," +
" DamageCrops:int," +
" Source:string," +
" StormSummary:dynamic)";
KustoOperationResult response = kustoClient.execute(database, command);
printResultsAsValueList(command, response.getPrimaryResults());
}
}
}
public static void printResultsAsValueList(String command, KustoResultSetTable results) {
while (results.next()) {
System.out.println("\n" + "-".repeat(20) + "\n");
System.out.println("Command: " + command);
System.out.println("Result:");
KustoResultColumn[] columns = results.getColumns();
for (int i = 0; i < columns.length; i++) {
System.out.println("\t" + columns[i].getColumnName() + " - " + (results.getObject(i) == null ? "None" : results.getString(i)));
}
}
}
}
Executar a aplicação
Numa shell de comandos, utilize o seguinte comando para executar a sua aplicação:
# Change directory to the folder that contains the management commands project
dotnet run .
python management_commands.py
Num ambiente de Node.js:
node management-commands.js
Num ambiente de browser, utilize o comando adequado para executar a sua aplicação. Por exemplo, para Vite-React:
npm run dev
mvn install exec:java -Dexec.mainClass="<groupId>.ManagementCommands"
Deverá ver um resultado semelhante ao seguinte:
--------------------
Command: .create table MyStormEvents
(StartTime:datetime,
EndTime:datetime,
State:string,
DamageProperty:int,
Source:string,
StormSummary:dynamic)
Result:
TableName - MyStormEvents
Schema - {"Name":"MyStormEvents","OrderedColumns":[{"Name":"StartTime","Type":"System.DateTime","CslType":"datetime"},{"Name":"EndTime","Type":"System.DateTime","CslType":"datetime"},{"Name":"State","Type":"System.String","CslType":"string"},{"Name":"DamageProperty","Type":"System.Int32","CslType":"int"},{"Name":"Source","Type":"System.String","CslType":"string"},{"Name":"StormSummary","Type":"System.Object","CslType":"dynamic"}]}
DatabaseName - MyDatabaseName
Folder - None
DocString - None
Alterar a política de criação de batches de ingestão ao nível da tabela
Pode personalizar o comportamento de criação de batches de ingestão para tabelas ao alterar a política de tabela correspondente. Para obter mais informações, veja IngestionBatching policy (Política IngestionBatching ).
Nota
Se não especificar todos os parâmetros de um PolicyObject , os parâmetros não especificados serão definidos como valores predefinidos . Por exemplo, especificar apenas "MaximumBatchingTimeSpan" resultará na predefinição "MaximumNumberOfItems" e "MaximumRawDataSizeMB".
Por exemplo, pode modificar a aplicação para alterar o valor de tempo limite da política de criação de batches de ingestão para 30 segundos ao alterar a ingestionBatching
política para a MyStormEvents
tabela com o seguinte comando:
// Reduce the default batching timeout to 30 seconds
command = @$".alter-merge table {table} policy ingestionbatching '{{ ""MaximumBatchingTimeSpan"":""00:00:30"" }}'";
using (var response = kustoClient.ExecuteControlCommand(database, command, null))
{
PrintResultsAsValueList(command, response);
}
# Reduce the default batching timeout to 30 seconds
command = ".alter-merge table " + table + " policy ingestionbatching '{ \"MaximumBatchingTimeSpan\":\"00:00:30\" }'"
response = kusto_client.execute_mgmt(database, command)
print_result_as_value_list(command, response)
// Reduce the default batching timeout to 30 seconds
command = ".alter-merge table " + table + " policy ingestionbatching '{ \"MaximumBatchingTimeSpan\":\"00:00:30\" }'"
response = await kustoClient.executeMgmt(database, command)
printResultsAsValueList(command, response)
// Reduce the default batching timeout to 30 seconds
command = ".alter-merge table " + table + " policy ingestionbatching '{ \"MaximumBatchingTimeSpan\":\"00:00:30\" }'";
response = kusto_client.execute(database, command);
printResultsAsValueList(command, response.getPrimaryResults());
Quando adicionar o código à sua aplicação e executá-lo, deverá ver um resultado semelhante ao seguinte:
--------------------
Command: .alter-merge table MyStormEvents policy ingestionbatching '{ "MaximumBatchingTimeSpan":"00:00:30" }'
Result:
PolicyName - IngestionBatchingPolicy
EntityName - [YourDatabase].[MyStormEvents]
Policy - {
"MaximumBatchingTimeSpan": "00:00:30",
"MaximumNumberOfItems": 500,
"MaximumRawDataSizeMB": 1024
}
ChildEntities - None
EntityType - Table
Mostrar a política de retenção ao nível da base de dados
Pode utilizar comandos de gestão para apresentar a política de retenção de uma base de dados.
Por exemplo, pode modificar a aplicação para apresentar a política de retenção da base de dados com o seguinte código. O resultado é organizado para projetar duas colunas do resultado:
// Show the database retention policy (drop some columns from the result)
command = @$".show database {database} policy retention | project-away ChildEntities, EntityType";
using (var response = kustoClient.ExecuteControlCommand(database, command, null)) {
PrintResultsAsValueList(command, response);
}
# Show the database retention policy (drop some columns from the result)
command = ".show database " + database + " policy retention | project-away ChildEntities, EntityType"
response = kusto_client.execute_mgmt(database, command)
print_result_as_value_list(command, response)
// Show the database retention policy (drop some columns from the result)
command = ".show database " + database + " policy retention | project-away ChildEntities, EntityType"
response = await kustoClient.executeMgmt(database, command)
printResultsAsValueList(command, response)
// Show the database retention policy (drop some columns from the result)
command = ".show database " + database + " policy retention | project-away ChildEntities, EntityType";
response = kusto_client.execute(database, command);
printResultsAsValueList(command, response.getPrimaryResults());
Quando adicionar o código à sua aplicação e executá-lo, deverá ver um resultado semelhante ao seguinte:
--------------------
Command: .show database YourDatabase policy retention | project-away ChildEntities, EntityType
Result:
PolicyName - RetentionPolicy
EntityName - [YourDatabase]
Policy - {
"SoftDeletePeriod": "365.00:00:00",
"Recoverability": "Enabled"
}
Passo seguinte