title | description | services | author | ms.author | ms.reviewer | ms.service | ms.topic | ms.date |
---|---|---|---|---|---|---|---|---|
Quickstart: Ingest data using the Azure Data Explorer .NET Standard SDK (Preview) |
In this quickstart, you learn how to ingest (load) data into Azure Data Explorer using .NET Standard SDK. |
data-explorer |
orspod |
v-orspod |
mblythe |
data-explorer |
quickstart |
11/18/2018 |
Azure Data Explorer (ADX) is a fast and highly scalable data exploration service for log and telemetry data. ADX provides two client libraries for .NET Standard: an ingest library and a data library. These libraries enable you to ingest (load) data into a cluster and query data from your code. In this quickstart, you first create a table and data mapping in a test cluster. You then queue an ingestion to the cluster and validate the results.
-
If you don't have an Azure subscription, create a free Azure account before you begin.
Install-Package Microsoft.Azure.Kusto.Ingest.NETStandard
To authenticate an application, Azure Data Explorer uses your AAD tenant ID. To find your tenant ID, use the following URL, substituting your domain for YourDomain.
https://login.windows.net/<YourDomain>/.well-known/openid-configuration/
For example, if your domain is contoso.com, the URL is: https://login.windows.net/contoso.com/.well-known/openid-configuration/. Click this URL to see the results; the first line is as follows.
"authorization_endpoint":"https://login.windows.net/6babcaad-604b-40ac-a9d7-9fd97c0b779f/oauth2/authorize"
The tenant ID in this case is 6babcaad-604b-40ac-a9d7-9fd97c0b779f
.
This example uses an AAD user and password for authentication to access the cluster. You can also use AAD application certificate and AAD application key. Set the your values for tenantId
, user
, and password
before running this code.
var tenantId = "<TenantId>";
var user = "<User>";
var password = "<Password>";
Now construct the connection string. You create the destination table and mapping in a later step.
var kustoUri = "https://<ClusterName>.<Region>.kusto.windows.net:443/";
var database = "<DatabaseName>";
var kustoConnectionStringBuilder =
new KustoConnectionStringBuilder(kustoUri)
{
FederatedSecurity = true,
InitialCatalog = database,
UserID = user,
Password = password,
Authority = tenantId
};
Set the path for the source file. This example uses a sample file hosted on Azure Blob Storage. The StormEvents sample data set contains weather-related data from the National Centers for Environmental Information.
var blobPath = "https://kustosamplefiles.blob.core.windows.net/samplefiles/StormEvents.csv?st=2018-08-31T22%3A02%3A25Z&se=2020-09-01T22%3A02%3A00Z&sp=r&sv=2018-03-28&sr=b&sig=LQIbomcKI8Ooz425hWtjeq6d61uEaq21UVX7YrM61N4%3D";
Create a table named StormEvents
that matches the schema of the data in the StormEvents.csv
file.
var table = "StormEvents";
using (var kustoClient = KustoClientFactory.CreateCslAdminProvider(kustoConnectionStringBuilder))
{
var command =
CslCommandGenerator.GenerateTableCreateCommand(
table,
new[]
{
Tuple.Create("StartTime", "System.DateTime"),
Tuple.Create("EndTime", "System.DateTime"),
Tuple.Create("EpisodeId", "System.Int32"),
Tuple.Create("EventId", "System.Int32"),
Tuple.Create("State", "System.String"),
Tuple.Create("EventType", "System.String"),
Tuple.Create("InjuriesDirect", "System.Int32"),
Tuple.Create("DeathsDirect", "System.Int32"),
Tuple.Create("DeathsIndirect", "System.Int32"),
Tuple.Create("DamageProperty", "System.Int32"),
Tuple.Create("DamageCrops", "System.Int32"),
Tuple.Create("Source", "System.String"),
Tuple.Create("BeginLocation", "System.String"),
Tuple.Create("EndLocation", "System.String"),
Tuple.Create("BeginLat", "System.Double"),
Tuple.Create("BeginLon", "System.Double"),
Tuple.Create("EndLat", "System.Double"),
Tuple.Create("EndLon", "System.Double"),
Tuple.Create("EpisodeNarrative", "System.String"),
Tuple.Create("EventNarrative", "System.String"),
Tuple.Create("StormSummary", "System.Object"),
});
kustoClient.ExecuteControlCommand(command);
}
Map the incoming CSV data to the column names used when creating the table. Provision a CSV column mapping object on that table
var tableMapping = "StormEvents_CSV_Mapping";
using (var kustoClient = KustoClientFactory.CreateCslAdminProvider(kustoConnectionStringBuilder))
{
var command =
CslCommandGenerator.GenerateTableCsvMappingCreateCommand(
table,
tableMapping,
new[]
{
new CsvColumnMapping { ColumnName = "StartTime", Ordinal = 0 },
new CsvColumnMapping { ColumnName = "EndTime", Ordinal = 1 },
new CsvColumnMapping { ColumnName = "EventId", Ordinal = 3 },
new CsvColumnMapping { ColumnName = "State", Ordinal = 4 },
new CsvColumnMapping { ColumnName = "InjuriesDirect", Ordinal = 6 },
new CsvColumnMapping { ColumnName = "InjuriesIndirect", Ordinal = 7 },
new CsvColumnMapping { ColumnName = "DeathsDirect", Ordinal = 8 },
new CsvColumnMapping { ColumnName = "DeathsIndirect", Ordinal = 9 },
new CsvColumnMapping { ColumnName = "DamageProperty", Ordinal = 10 },
new CsvColumnMapping { ColumnName = "DamageCrops", Ordinal = 11 },
new CsvColumnMapping { ColumnName = "Source", Ordinal = 12 },
new CsvColumnMapping { ColumnName = "BeginLocation", Ordinal = 13 },
new CsvColumnMapping { ColumnName = "EndLocation", Ordinal = 14 },
new CsvColumnMapping { ColumnName = "BeginLat", Ordinal = 16 },
new CsvColumnMapping { ColumnName = "BeginLon", Ordinal = 17 },
new CsvColumnMapping { ColumnName = "EndLat", Ordinal = 18 },
new CsvColumnMapping { ColumnName = "EndLon", Ordinal = 19 },
new CsvColumnMapping { ColumnName = "EpisodeNarrative", Ordinal = 20 },
new CsvColumnMapping { ColumnName = "EventNarrative", Ordinal = 21 },
new CsvColumnMapping { ColumnName = "StormSummary", Ordinal = 22 },
});
kustoClient.ExecuteControlCommand(command);
}
Queue a message to pull data from blob storage and ingest that data into ADX.
var ingestUri = "https://ingest-<ClusterName>.<Region>.kusto.windows.net:443/";
var ingestConnectionStringBuilder =
new KustoConnectionStringBuilder(ingestUri)
{
FederatedSecurity = true,
InitialCatalog = database,
UserID = user,
Password = password,
Authority = tenantId
};
using (var ingestClient = KustoIngestFactory.CreateQueuedIngestClient(ingestConnectionStringBuilder))
{
var properties =
new KustoQueuedIngestionProperties(database, table)
{
Format = DataSourceFormat.csv,
CSVMappingReference = tableMapping,
IgnoreFirstRecord = true
};
ingestClient.IngestFromSingleBlob(blobPath, deleteSourceOnSuccess: false, ingestionProperties: properties);
}
Wait for five to ten minutes for the queued ingestion to schedule the ingest and load the data into ADX. Then run the following code to get the count of records in the StormEvents
table.
using (var cslQueryProvider = KustoClientFactory.CreateCslQueryProvider(kustoConnectionStringBuilder))
{
var query = $"{table} | count";
var results = cslQueryProvider.ExecuteQuery<long>(query);
Console.WriteLine(results.Single());
}
Sign in to https://dataexplorer.azure.com and connect to your cluster. Run the following command in your database to see if there were any ingestion failures in the last four hours. Replace the database name before running.
.show ingestion failures
| where FailedOn > ago(4h) and Database == "<DatabaseName>"
Run the following command to view the status of all ingestion operations in the last four hours. Replace the database name before running.
.show operations
| where StartedOn > ago(4h) and Database == "<DatabaseName>" and Operation == "DataIngestPull"
| summarize arg_max(LastUpdatedOn, *) by OperationId
If you plan to follow our other quickstarts and tutorials, keep the resources you created. If not, run the following command in your database to clean up the StormEvents
table.
.drop table StormEvents
[!div class="nextstepaction"] Write queries