Skip to content

Commit

Permalink
[Monitor] Fix activity-log list issues. (#7525)
Browse files Browse the repository at this point in the history
* Fix #5608. Fix #4885.

* Update Metric command.
  • Loading branch information
tjprescott authored Oct 18, 2018
1 parent 3a0db96 commit e0b46a9
Show file tree
Hide file tree
Showing 17 changed files with 568 additions and 331 deletions.
3 changes: 1 addition & 2 deletions azure-cli2017.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -558,19 +558,18 @@
<Compile Include="command_modules\azure-cli-maps\__init__.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\commands.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\actions.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\custom.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\grammar\MetricAlertConditionLexer.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\grammar\MetricAlertConditionListener.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\grammar\MetricAlertConditionParser.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\grammar\MetricAlertConditionValidator.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\grammar\__init__.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\operations\action_groups.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\operations\activity_log.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\operations\activity_log_alerts.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\operations\autoscale_settings.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\operations\diagnostics_settings.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\operations\log_profiles.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\operations\metric_alert.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\tests\latest\test_activity_log_components.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\tests\latest\test_activity_log_scenario.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\tests\latest\test_monitor_action_groups.py" />
<Compile Include="command_modules\azure-cli-monitor\azure\cli\command_modules\monitor\tests\latest\test_monitor_activity_log_alert.py" />
Expand Down
9 changes: 6 additions & 3 deletions src/azure-cli-core/azure/cli/core/commands/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,23 @@ def get_location_completion_list(cmd, prefix, namespace, **kwargs): # pylint: d
# pylint: disable=redefined-builtin
def get_datetime_type(help=None, date=True, time=True, timezone=True):

help_string = help + ' ' or ''
help_string = help + ' ' if help else ''
accepted_formats = []
if date:
accepted_formats.append('date (yyyy-mm-dd)')
if time:
accepted_formats.append('time (hh:mm:ss.xxxxx)')
if timezone:
accepted_formats.append('timezone (+/-hh:mm)')
help_string = help_string + 'Format: ' + ', '.join(accepted_formats)
help_string = help_string + 'Format: ' + ' '.join(accepted_formats)

# pylint: disable=too-few-public-methods
class DatetimeAction(argparse.Action):

def __call__(self, parser, namespace, values, option_string=None):
""" Parse a date value and return the ISO8601 string. """
import dateutil.parser
import dateutil.tz

value_string = ' '.join(values)
dt_val = None
Expand All @@ -62,10 +63,12 @@ def __call__(self, parser, namespace, values, option_string=None):
pass

# TODO: custom parsing attempts here

if not dt_val:
raise CLIError("Unable to parse: '{}'. Expected format: {}".format(value_string, help_string))

if not dt_val.tzinfo and timezone:
dt_val = dt_val.replace(tzinfo=dateutil.tz.tzlocal())

# Issue warning if any supplied data will be ignored
if not date and any([dt_val.day, dt_val.month, dt_val.year]):
logger.warning('Date info will be ignored in %s.', value_string)
Expand Down
9 changes: 9 additions & 0 deletions src/command_modules/azure-cli-monitor/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ Release History

0.2.5
+++++
* `monitor activity-log list`:
Allow listing all events at the subscription level.
Added `--offset` parameter to more easily create time queries.
Improved validation for --start-time and --end-time to use wider range of ISO8601 formats and more user-friendly datetime formats.
Added `--namespace` as alias for deprecated option `--resource-provider`.
Deprecated `--filters` because no values other than those with strongly-typed options are supported by the service.
* `monitor metrics list`:
Added `--offset` parameter to more easily create time queries.
Improved validation for --start-time and --end-time to use wider range of ISO8601 formats and more user-friendly datetime formats.
* `monitor diagnostic-settings create`: Improve validation for arguments `--event-hub` and `--event-hub-rule`.

0.2.4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# --------------------------------------------------------------------------------------------

from azure.cli.core import AzCommandsLoader
from azure.cli.core.commands import AzArgumentContext
from azure.cli.core.commands import AzArgumentContext, CliCommandType

from azure.cli.command_modules.monitor._help import helps # pylint: disable=unused-import

Expand Down Expand Up @@ -32,9 +32,14 @@ def resource_parameter(self, dest, arg_group=None, required=True, skip_validator
class MonitorCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.command_modules.monitor._exception_handler import monitor_exception_handler
monitor_custom = CliCommandType(
operations_tmpl='azure.cli.command_modules.monitor.custom#{}',
exception_handler=monitor_exception_handler)
super(MonitorCommandsLoader, self).__init__(cli_ctx=cli_ctx,
min_profile='2017-03-10-profile',
argument_context_cls=MonitorArgumentContext)
argument_context_cls=MonitorArgumentContext,
custom_command_type=monitor_custom)

def load_command_table(self, args):
from azure.cli.command_modules.monitor.commands import load_command_table
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,30 +133,27 @@
short-summary: List the metric values for a resource.
parameters:
- name: --aggregation
type: string
short-summary: The list of aggregation types (space-separated) to retrieve.
- name: --interval
type: string
short-summary: The interval of the metric query. In ISO 8601 duration format, eg "PT1M"
- name: --start-time
type: string
short-summary: >
The start time of the query. In ISO format with explicit indication of timezone, 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500.
Defaults to 1 Hour prior to the current time.
- name: --end-time
type: string
short-summary: >
The end time of the query. In ISO format with explicit indication of timezone, 1970-01-01T00:00:00Z, 1970-01-01T00:00:00-0500.
Defaults to the current time.
The interval over which to aggregate metrics, in ##h##m format.
- name: --filter
type: string
short-summary: A string used to reduce the set of metric data returned. eg. "BlobType eq '*'"
long-summary: 'For a full list of filters, see the filter string reference at https://docs.microsoft.com/en-us/rest/api/monitor/metrics/list'
- name: --metadata
short-summary: Returns the metadata values instead of metric data
- name: --dimension
type: string
short-summary: The list of dimensions (space-separated) the metrics are queried into.
- name: --namespace
short-summary: Namespace to query metric definitions for.
- name: --offset
short-summary: >
Time offset of the query range, in ##d##h format.
long-summary: >
Can be used with either --start-time or --end-time. If used with --start-time, then
the end time will be calculated by adding the offset. If used with --end-time (default), then
the start time will be calculated by subtracting the offset. If --start-time and --end-time are
provided, then --offset will be ignored.
examples:
- name: List a VM's CPU usage for the past hour
text: >
Expand Down Expand Up @@ -822,37 +819,38 @@

helps['monitor activity-log list'] = """
type: command
short-summary: List events from the activity log.
short-summary: List and query activity log events.
parameters:
- name: --filters
short-summary: >
The OData filter for the list activity logs. If this argument is provided OData Filter
Arguments will be ignored.
- name: --correlation-id
short-summary: Correlation ID of the query.
- name: --resource-group
short-summary: Resource group to query.
short-summary: Correlation ID to query.
- name: --resource-id
short-summary: Identifier of the resource.
- name: --resource-provider
short-summary: Resource provider
- name: --start-time
short-summary: >
Start time of the query. ISO format with explicit indication of timezone: 1970-01-01T00:00:00Z,
1970-01-01T00:00:00-0500. Defaults to 1 Hour prior to the current time.
- name: --end-time
short-summary: >
End time of the query. ISO format with explicit indication of timezone: 1970-01-01T00:00:00Z,
1970-01-01T00:00:00-0500. Defaults to current time.
short-summary: ARM ID of a resource.
- name: --namespace
short-summary: Resource provider namespace.
- name: --caller
short-summary: Caller to look for when querying.
short-summary: Caller to query for, such as an e-mail address or service principal ID.
- name: --status
short-summary: >
Status value to query (ex: Failed)
Status to query for (ex: Failed)
- name: --max-events
short-summary: Maximum number of records to be returned by the command.
short-summary: Maximum number of records to return.
- name: --select
short-summary: Space-separated list of event names to select.
short-summary: Space-separated list of properties to return.
- name: --offset
short-summary: >
Time offset of the query range, in ##d##h format.
long-summary: >
Can be used with either --start-time or --end-time. If used with --start-time, then
the end time will be calculated by adding the offset. If used with --end-time (default), then
the start time will be calculated by subtracting the offset. If --start-time and --end-time are
provided, then --offset will be ignored.
examples:
- name: List all events from July 1st, looking forward one week.
text: az monitor activity-log list --start-date 2018-07-01 --offset 7d
- name: List events within the past six hours based on a correlation ID.
text: az monitor activity-log list --correlation-id b5eac9d2-e829-4c9a-9efb-586d19417c5f
- name: List events within the past hour based on resource group.
text: az monitor activity-log list -g {ResourceGroup} --offset 1h
"""

helps['monitor activity-log list-categories'] = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
from azure.cli.core.util import get_json_object

from azure.cli.core.commands.parameters import (
get_location_type, tags_type, get_three_state_flag, get_enum_type, get_datetime_type)
get_location_type, tags_type, get_three_state_flag, get_enum_type, get_datetime_type, resource_group_name_type)
from azure.cli.core.commands.validators import get_default_location_from_resource_group

from azure.cli.command_modules.monitor.actions import (
AlertAddAction, AlertRemoveAction, ConditionAction, AutoscaleAddAction, AutoscaleRemoveAction,
AutoscaleScaleAction, AutoscaleConditionAction, period_type,
AutoscaleScaleAction, AutoscaleConditionAction, get_period_type,
timezone_offset_type, timezone_name_type, MetricAlertConditionAction, MetricAlertAddAction)
from azure.cli.command_modules.monitor.util import get_operator_map, get_aggregation_map
from azure.cli.command_modules.monitor.validators import (
process_webhook_prop, validate_autoscale_recurrence, validate_autoscale_timegrain, get_action_group_validator,
get_action_group_id_validator)
get_action_group_id_validator, validate_metric_dimension)


# pylint: disable=line-too-long, too-many-statements
def load_arguments(self, _):
from azure.mgmt.monitor.models import ConditionOperator, TimeAggregationOperator
from azure.mgmt.monitor.models import ConditionOperator, TimeAggregationOperator, EventData

name_arg_type = CLIArgumentType(options_list=['--name', '-n'], metavar='NAME')
webhook_prop_type = CLIArgumentType(validator=process_webhook_prop, nargs='*')
Expand Down Expand Up @@ -73,7 +73,7 @@ def load_arguments(self, _):
c.argument('operator', arg_type=get_enum_type(get_operator_map().keys()))
c.argument('threshold')
c.argument('aggregation', arg_type=get_enum_type(get_aggregation_map().keys()))
c.argument('period', type=period_type)
c.argument('period', type=get_period_type())

for scope in ['monitor alert show-incident', 'monitor alert list-incidents']:
with self.argument_context(scope) as c:
Expand All @@ -92,26 +92,30 @@ def load_arguments(self, _):
c.resource_parameter('resource_uri', arg_group='Target Resource')

with self.argument_context('monitor metrics list') as c:
from .validators import (process_metric_timespan, process_metric_aggregation, process_metric_result_type,
process_metric_dimension, validate_metric_names)
from azure.mgmt.monitor.models import AggregationType
c.resource_parameter('resource_uri', arg_group='Target Resource')
c.extra('start_time', options_list=['--start-time'], validator=process_metric_timespan, arg_group='Time')
c.extra('end_time', options_list=['--end-time'], arg_group='Time')
c.extra('metadata', options_list=['--metadata'], action='store_true', validator=process_metric_result_type)
c.extra('dimension', options_list=['--dimension'], nargs='*', validator=process_metric_dimension)
c.argument('interval', arg_group='Time')
c.argument('aggregation', arg_type=get_enum_type(t for t in AggregationType if t.name != 'none'), nargs='*', validator=process_metric_aggregation)
c.argument('metricnames', options_list=['--metrics'], nargs='+', help='Space-separated list of metric names to retrieve.', validator=validate_metric_names)
c.ignore('timespan', 'result_type')
c.resource_parameter('resource', arg_group='Target Resource')
c.argument('metadata', action='store_true')
c.argument('dimension', nargs='*', validator=validate_metric_dimension)
c.argument('aggregation', arg_type=get_enum_type(t for t in AggregationType if t.name != 'none'), nargs='*')
c.argument('metrics', nargs='+', help='Space-separated list of metric names to retrieve.')
c.argument('orderby', help='Aggregation to use for sorting results and the direction of the sort. Only one order can be specificed. Examples: sum asc')
c.argument('top', help='Max number of records to retrieve. Valid only if --filter used.')
c.argument('filters', options_list='--filter')
c.argument('metric_namespace', options_list='--namespace')

with self.argument_context('monitor metrics list', arg_group='Time') as c:
c.argument('start_time', arg_type=get_datetime_type(help='Start time of the query.'))
c.argument('end_time', arg_type=get_datetime_type(help='End time of the query. Defaults to the current time.'))
c.argument('offset', type=get_period_type(as_timedelta=True))
c.argument('interval', arg_group='Time', type=get_period_type())
# endregion

# region MetricAlerts
with self.argument_context('monitor metrics alert') as c:
c.argument('rule_name', name_arg_type, id_part='name', help='Name of the alert rule.')
c.argument('severity', type=int, help='Severity of the alert from 0 (low) to 4 (high).')
c.argument('window_size', type=period_type, help='Time over which to aggregate metrics in "##h##m##s" format.')
c.argument('evaluation_frequency', type=period_type, help='Frequency with which to evaluate the rule in "##h##m##s" format.')
c.argument('window_size', type=get_period_type(), help='Time over which to aggregate metrics in "##h##m##s" format.')
c.argument('evaluation_frequency', type=get_period_type(), help='Frequency with which to evaluate the rule in "##h##m##s" format.')
c.argument('auto_mitigate', arg_type=get_three_state_flag(), help='Automatically resolve the alert.')
c.argument('condition', options_list=['--condition'], action=MetricAlertConditionAction, nargs='+')
c.argument('description', help='Free-text description of the rule.')
Expand Down Expand Up @@ -249,17 +253,23 @@ def load_arguments(self, _):

# region ActivityLog
with self.argument_context('monitor activity-log list') as c:
c.argument('select', nargs='+')
activity_log_props = [x['key'] for x in EventData()._attribute_map.values()] # pylint: disable=protected-access
c.argument('select', nargs='+', arg_type=get_enum_type(activity_log_props))
c.argument('max_events', type=int)

with self.argument_context('monitor activity-log list', arg_group='Time') as c:
c.argument('start_time', arg_type=get_datetime_type(help='Start time of the query.'))
c.argument('end_time', arg_type=get_datetime_type(help='End time of the query. Defaults to the current time.'))
c.argument('offset', type=get_period_type(as_timedelta=True))

with self.argument_context('monitor activity-log list', arg_group='OData Filter') as c:
with self.argument_context('monitor activity-log list', arg_group='Filter') as c:
c.argument('filters', deprecate_info=c.deprecate(target='--filters', hide=True, expiration='2.1.0'), help='OData filters. Will ignore other filter arguments.')
c.argument('correlation_id')
c.argument('caller')
c.argument('resource_group')
c.argument('resource_group', resource_group_name_type)
c.argument('resource_id')
c.argument('resource_provider')
c.argument('resource_provider', options_list=['--namespace', c.deprecate(target='--resource-provider', redirect='--namespace', hide=True, expiration='2.1.0')])
c.argument('caller')
c.argument('status')
c.argument('start_time')
c.argument('end_time')
# endregion

# region ActionGroup
Expand Down
Loading

0 comments on commit e0b46a9

Please sign in to comment.