-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add preview Log Analytics query extension #250
Changes from 12 commits
72d3286
005bccc
05a84d4
073f0fd
c02dfca
8f40bb4
46eea30
9417f43
6844dd0
edcb154
7fa4cbe
7a1454a
531d1d4
37d1574
5c9dbdc
6d0288f
5b826d7
ba14a67
87db7df
fd5356b
345c3db
53fddc9
9dd23c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,4 +34,6 @@ | |
|
||
/src/express-route-cross-connection/ @tjprescott | ||
|
||
/src/loganalytics/ @alexeldeib | ||
|
||
/src/mesh/ @linggengmsft |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
0.1.1 | ||
++++++++++++++++++ | ||
|
||
* Fix homepage | ||
|
||
0.1.0 | ||
++++++++++++++++++ | ||
|
||
* Initial release. | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Commands for working with Azure Log Analytics | ||
============================================== |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from azure.cli.core import AzCommandsLoader | ||
|
||
from azext_loganalytics._help import helps # pylint: disable=unused-import | ||
|
||
|
||
class LogAnalyticsCommandsLoader(AzCommandsLoader): | ||
|
||
def __init__(self, cli_ctx=None): | ||
from azure.cli.core.commands import CliCommandType | ||
from azext_loganalytics._client_factory import loganalytics_data_plane_client | ||
loganalytics_custom = CliCommandType( | ||
operations_tmpl='azext_loganalytics.custom#{}', | ||
client_factory=loganalytics_data_plane_client | ||
) | ||
|
||
super(LogAnalyticsCommandsLoader, self).__init__( | ||
cli_ctx=cli_ctx, | ||
custom_command_type=loganalytics_custom | ||
) | ||
|
||
def load_command_table(self, args): | ||
from azext_loganalytics.commands import load_command_table | ||
load_command_table(self, args) | ||
return self.command_table | ||
|
||
def load_arguments(self, command): | ||
from azext_loganalytics._params import load_arguments | ||
load_arguments(self, command) | ||
|
||
|
||
COMMAND_LOADER_CLS = LogAnalyticsCommandsLoader |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
|
||
def loganalytics_data_plane_client(cli_ctx, _): | ||
"""Initialize Log Analytics data client for use with CLI.""" | ||
from .vendored_sdks.loganalytics import LogAnalyticsDataClient | ||
from azure.cli.core._profile import Profile | ||
profile = Profile(cli_ctx=cli_ctx) | ||
cred, _, _ = profile.get_login_credentials( | ||
resource="https://api.loganalytics.io") | ||
return LogAnalyticsDataClient(cred) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from knack.help_files import helps | ||
|
||
# pylint: disable=line-too-long | ||
|
||
helps['monitor loganalytics query'] = """ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. log-analytics |
||
type: command | ||
short-summary: Query a Log Analytics workspace. | ||
parameters: | ||
- workspace: --workspace -w | ||
type: string | ||
short-summary: GUID of the Log Analytics workspace. | ||
- kql: --kql -k | ||
type: string | ||
short-summary: Query to execute over the Log Analytics data. | ||
- timespan: --timespan -t | ||
type: string | ||
short-summary: Timespan over which to query data. Defaults to all data. | ||
- workspaces: --workspaces | ||
type: array | ||
short-summary: Additional workspaces to union data for querying. Specify additional workspace IDs separated by commas. | ||
examples: | ||
- name: | ||
""" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
# pylint: disable=line-too-long | ||
|
||
|
||
def load_arguments(self, _): | ||
with self.argument_context('loganalytics') as c: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
c.argument('workspace', options_list=['--workspace', '-w'], help='GUID of the Log Analytics Workspace', required=True) | ||
c.argument('kql', help='Query to execute over Log Analytics data.', required=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you don't need the |
||
c.argument('timespan', options_list=['--timespan', '-t'], help='Timespan over which to query. Defaults to querying all available data.') | ||
c.argument('workspaces', nargs='+', help='Optional additional workspaces over which to join data for the query.') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"azext.isPreview": true | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
# pylint: disable=line-too-long | ||
|
||
|
||
def load_command_table(self, _): | ||
|
||
with self.command_group('monitor log-analytics') as g: | ||
g.custom_command('query', 'execute_query') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from knack.log import get_logger | ||
|
||
logger = get_logger(__name__) | ||
|
||
|
||
def execute_query(client, workspace, kql, timespan=None, workspaces=None): | ||
"""Executes a query against the provided Log Analytics workspace.""" | ||
from .vendored_sdks.loganalytics.models import QueryBody | ||
return client.query(workspace, QueryBody(query=kql, timespan=timespan, workspaces=workspaces)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
interactions: | ||
- request: | ||
body: '{"query": "Heartbeat | getschema"}' | ||
headers: | ||
Accept: [application/json] | ||
Accept-Encoding: ['gzip, deflate'] | ||
Connection: [keep-alive] | ||
Content-Length: ['34'] | ||
Content-Type: [application/json; charset=utf-8] | ||
User-Agent: [python/3.6.4 (Windows-10-10.0.17134-SP0) requests/2.19.1 msrest/0.5.3 | ||
azure-loganalytics/0.1.0] | ||
method: POST | ||
uri: https://api.loganalytics.io/v1/workspaces/cab864ad-d0c1-496b-bc5e-4418315621bf/query | ||
response: | ||
body: {string: '{"tables":[{"name":"getschema","columns":[{"name":"ColumnName","type":"string"},{"name":"ColumnOrdinal","type":"int"},{"name":"DataType","type":"string"},{"name":"ColumnType","type":"string"}],"rows":[["TenantId",0,"System.String","string"],["SourceSystem",1,"System.String","string"],["TimeGenerated",2,"System.DateTime","datetime"],["MG",3,"System.String","string"],["ManagementGroupName",4,"System.String","string"],["SourceComputerId",5,"System.String","string"],["ComputerIP",6,"System.String","string"],["Computer",7,"System.String","string"],["Category",8,"System.String","string"],["OSType",9,"System.String","string"],["OSName",10,"System.String","string"],["OSMajorVersion",11,"System.String","string"],["OSMinorVersion",12,"System.String","string"],["Version",13,"System.String","string"],["SCAgentChannel",14,"System.String","string"],["IsGatewayInstalled",15,"System.SByte","bool"],["RemoteIPLongitude",16,"System.Double","real"],["RemoteIPLatitude",17,"System.Double","real"],["RemoteIPCountry",18,"System.String","string"],["SubscriptionId",19,"System.String","string"],["ResourceGroup",20,"System.String","string"],["ResourceProvider",21,"System.String","string"],["Resource",22,"System.String","string"],["ResourceId",23,"System.String","string"],["ResourceType",24,"System.String","string"],["ComputerEnvironment",25,"System.String","string"],["Solutions",26,"System.String","string"],["VMUUID",27,"System.String","string"],["Type",28,"System.String","string"]]}]}'} | ||
headers: | ||
access-control-allow-origin: ['*'] | ||
access-control-expose-headers: ['Retry-After,Age,WWW-Authenticate,x-resource-identities,x-ms-status-location'] | ||
connection: [keep-alive] | ||
content-length: ['1482'] | ||
content-location: ['https://eastus.api.loganalytics.io/v1/workspaces/cab864ad-d0c1-496b-bc5e-4418315621bf/query'] | ||
content-type: [application/json; charset=utf-8] | ||
date: ['Mon, 16 Jul 2018 18:19:50 GMT'] | ||
server: [nginx] | ||
strict-transport-security: [max-age=31536000000; includeSubDomains, max-age=31536000; | ||
includeSubDomains] | ||
transfer-encoding: [chunked] | ||
vary: [Accept-Encoding] | ||
via: [1.1 draft-oms-green.9ae239f1-88dc-11e8-aedf-70b3d5800006] | ||
x-content-type-options: [nosniff] | ||
status: {code: 200, message: OK} | ||
- request: | ||
body: '{"query": "Heartbeat | getschema"}' | ||
headers: | ||
Accept: [application/json] | ||
Accept-Encoding: ['gzip, deflate'] | ||
Connection: [keep-alive] | ||
Content-Length: ['34'] | ||
Content-Type: [application/json; charset=utf-8] | ||
User-Agent: [python/3.6.4 (Windows-10-10.0.17134-SP0) requests/2.19.1 msrest/0.5.3 | ||
azure-loganalytics/0.1.0] | ||
method: POST | ||
uri: https://api.loganalytics.io/v1/workspaces/cab864ad-d0c1-496b-bc5e-4418315621bf/query | ||
response: | ||
body: {string: '{"tables":[{"name":"getschema","columns":[{"name":"ColumnName","type":"string"},{"name":"ColumnOrdinal","type":"int"},{"name":"DataType","type":"string"},{"name":"ColumnType","type":"string"}],"rows":[["TenantId",0,"System.String","string"],["SourceSystem",1,"System.String","string"],["TimeGenerated",2,"System.DateTime","datetime"],["MG",3,"System.String","string"],["ManagementGroupName",4,"System.String","string"],["SourceComputerId",5,"System.String","string"],["ComputerIP",6,"System.String","string"],["Computer",7,"System.String","string"],["Category",8,"System.String","string"],["OSType",9,"System.String","string"],["OSName",10,"System.String","string"],["OSMajorVersion",11,"System.String","string"],["OSMinorVersion",12,"System.String","string"],["Version",13,"System.String","string"],["SCAgentChannel",14,"System.String","string"],["IsGatewayInstalled",15,"System.SByte","bool"],["RemoteIPLongitude",16,"System.Double","real"],["RemoteIPLatitude",17,"System.Double","real"],["RemoteIPCountry",18,"System.String","string"],["SubscriptionId",19,"System.String","string"],["ResourceGroup",20,"System.String","string"],["ResourceProvider",21,"System.String","string"],["Resource",22,"System.String","string"],["ResourceId",23,"System.String","string"],["ResourceType",24,"System.String","string"],["ComputerEnvironment",25,"System.String","string"],["Solutions",26,"System.String","string"],["VMUUID",27,"System.String","string"],["Type",28,"System.String","string"]]}]}'} | ||
headers: | ||
access-control-allow-origin: ['*'] | ||
access-control-expose-headers: ['Retry-After,Age,WWW-Authenticate,x-resource-identities,x-ms-status-location'] | ||
age: ['0'] | ||
connection: [keep-alive] | ||
content-length: ['1482'] | ||
content-location: ['https://eastus.api.loganalytics.io/v1/workspaces/cab864ad-d0c1-496b-bc5e-4418315621bf/query'] | ||
content-type: [application/json; charset=utf-8] | ||
date: ['Mon, 16 Jul 2018 18:19:50 GMT'] | ||
server: [nginx] | ||
strict-transport-security: [max-age=31536000000; includeSubDomains, max-age=31536000; | ||
includeSubDomains] | ||
transfer-encoding: [chunked] | ||
vary: [Accept-Encoding] | ||
via: [1.1 draft-oms-green.c01b97e7-888d-11e8-aedf-70b3d5800006] | ||
x-content-type-options: [nosniff] | ||
status: {code: 200, message: OK} | ||
version: 1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
# pylint: disable=line-too-long | ||
from azure.cli.testsdk import ScenarioTest | ||
|
||
|
||
class LogAnalyticsDataClientTests(ScenarioTest): | ||
"""Test class for Log Analytics data client.""" | ||
def test_query(self): | ||
"""Tests data plane query capabilities for Log Analytics.""" | ||
self.cmd('az loganalytics query -w cab864ad-d0c1-496b-bc5e-4418315621bf --kql "Heartbeat | getschema"', checks=[ | ||
self.check('tables[0].rows[0][0]', 'TenantId') | ||
]) | ||
query_result = self.cmd('az loganalytics query -w cab864ad-d0c1-496b-bc5e-4418315621bf --kql "Heartbeat | getschema"').get_output_in_json() | ||
assert len(query_result['tables'][0]['rows']) == 29 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test looks stale. Can you run your test again? that should also pick up some of the other problems i saw. |
||
assert isinstance(query_result['tables'][0]['rows'][0][1], (int, float, complex)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# coding=utf-8 | ||
# -------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for | ||
# license information. | ||
# | ||
# Code generated by Microsoft (R) AutoRest Code Generator. | ||
# Changes may cause incorrect behavior and will be lost if the code is | ||
# regenerated. | ||
# -------------------------------------------------------------------------- | ||
|
||
from .log_analytics_data_client import LogAnalyticsDataClient | ||
from .version import VERSION | ||
|
||
__all__ = ['LogAnalyticsDataClient'] | ||
|
||
__version__ = VERSION | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
start with version 0.1.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
edit: replied to stale comment