1// Copyright 2022 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15syntax = "proto3"; 16 17package google.cloud.timeseriesinsights.v1; 18 19import "google/api/annotations.proto"; 20import "google/api/client.proto"; 21import "google/api/field_behavior.proto"; 22import "google/api/resource.proto"; 23import "google/protobuf/duration.proto"; 24import "google/protobuf/empty.proto"; 25import "google/protobuf/timestamp.proto"; 26import "google/rpc/status.proto"; 27 28option cc_enable_arenas = true; 29option go_package = "cloud.google.com/go/timeseriesinsights/apiv1/timeseriesinsightspb;timeseriesinsightspb"; 30option java_multiple_files = true; 31option java_outer_classname = "TimeseriesInsightsProto"; 32option java_package = "com.google.cloud.timeseriesinsights.v1"; 33 34service TimeseriesInsightsController { 35 option (google.api.default_host) = "timeseriesinsights.googleapis.com"; 36 option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; 37 38 // Lists [DataSets][google.cloud.timeseriesinsights.v1.DataSet] under the project. 39 // 40 // The order of the results is unspecified but deterministic. Newly created 41 // [DataSets][google.cloud.timeseriesinsights.v1.DataSet] will not necessarily be added to the end 42 // of this list. 43 rpc ListDataSets(ListDataSetsRequest) returns (ListDataSetsResponse) { 44 option (google.api.http) = { 45 get: "/v1/{parent=projects/*/locations/*}/datasets" 46 additional_bindings { 47 get: "/v1/{parent=projects/*}/datasets" 48 } 49 }; 50 option (google.api.method_signature) = "parent"; 51 } 52 53 // Create a [DataSet][google.cloud.timeseriesinsights.v1.DataSet] from data stored on Cloud 54 // Storage. 55 // 56 // The data must stay immutable while we process the 57 // [DataSet][google.cloud.timeseriesinsights.v1.DataSet] creation; otherwise, undefined outcomes 58 // might result. For more information, see [DataSet][google.cloud.timeseriesinsights.v1.DataSet]. 59 rpc CreateDataSet(CreateDataSetRequest) returns (DataSet) { 60 option (google.api.http) = { 61 post: "/v1/{parent=projects/*/locations/*}/datasets" 62 body: "dataset" 63 additional_bindings { 64 post: "/v1/{parent=projects/*}/datasets" 65 body: "dataset" 66 } 67 }; 68 option (google.api.method_signature) = "parent,dataset"; 69 } 70 71 // Delete a [DataSet][google.cloud.timeseriesinsights.v1.DataSet] from the system. 72 // 73 // **NOTE**: If the [DataSet][google.cloud.timeseriesinsights.v1.DataSet] is still being 74 // processed, it will be aborted and deleted. 75 rpc DeleteDataSet(DeleteDataSetRequest) returns (google.protobuf.Empty) { 76 option (google.api.http) = { 77 delete: "/v1/{name=projects/*/locations/*/datasets/*}" 78 additional_bindings { 79 delete: "/v1/{name=projects/*/datasets/*}" 80 } 81 }; 82 option (google.api.method_signature) = "name"; 83 } 84 85 // Append events to a `LOADED` [DataSet][google.cloud.timeseriesinsights.v1.DataSet]. 86 rpc AppendEvents(AppendEventsRequest) returns (AppendEventsResponse) { 87 option (google.api.http) = { 88 post: "/v1/{dataset=projects/*/locations/*/datasets/*}:appendEvents" 89 body: "*" 90 additional_bindings { 91 post: "/v1/{dataset=projects/*/datasets/*}:appendEvents" 92 body: "*" 93 } 94 }; 95 option (google.api.method_signature) = "dataset,events"; 96 } 97 98 // Execute a Timeseries Insights query over a loaded 99 // [DataSet][google.cloud.timeseriesinsights.v1.DataSet]. 100 rpc QueryDataSet(QueryDataSetRequest) returns (QueryDataSetResponse) { 101 option (google.api.http) = { 102 post: "/v1/{name=projects/*/locations/*/datasets/*}:query" 103 body: "*" 104 additional_bindings { 105 post: "/v1/{name=projects/*/datasets/*}:query" 106 body: "*" 107 } 108 }; 109 } 110 111 // Evaluate an explicit slice from a loaded [DataSet][google.cloud.timeseriesinsights.v1.DataSet]. 112 rpc EvaluateSlice(EvaluateSliceRequest) returns (EvaluatedSlice) { 113 option (google.api.http) = { 114 post: "/v1/{dataset=projects/*/locations/*/datasets/*}:evaluateSlice" 115 body: "*" 116 additional_bindings { 117 post: "/v1/{dataset=projects/*/datasets/*}:evaluateSlice" 118 body: "*" 119 } 120 }; 121 } 122 123 // Evaluate an explicit timeseries. 124 rpc EvaluateTimeseries(EvaluateTimeseriesRequest) returns (EvaluatedSlice) { 125 option (google.api.http) = { 126 post: "/v1/{parent=projects/*/locations/*}/datasets:evaluateTimeseries" 127 body: "*" 128 additional_bindings { 129 post: "/v1/{parent=projects/*}/datasets:evaluateTimeseries" 130 body: "*" 131 } 132 }; 133 } 134} 135 136// Mapping of BigQuery columns to timestamp, group_id and dimensions. 137message BigqueryMapping { 138 // The column which should be used as the event timestamps. If not specified 139 // 'Timestamp' is used by default. The column may have TIMESTAMP or INT64 140 // type (the latter is interpreted as microseconds since the Unix epoch). 141 string timestamp_column = 1; 142 143 // The column which should be used as the group ID (grouping events into 144 // sessions). If not specified 'GroupId' is used by default, if the input 145 // table does not have such a column, random unique group IDs are 146 // generated automatically (different group ID per input row). 147 string group_id_column = 2; 148 149 // The list of columns that should be translated to dimensions. If empty, 150 // all columns are translated to dimensions. The timestamp and group_id 151 // columns should not be listed here again. Columns are expected to have 152 // primitive types (STRING, INT64, FLOAT64 or NUMERIC). 153 repeated string dimension_column = 3; 154} 155 156// A data source consists of multiple [Event][google.cloud.timeseriesinsights.v1.Event] objects stored on 157// Cloud Storage. Each Event should be in JSON format, with one Event 158// per line, also known as JSON Lines format. 159message DataSource { 160 // Data source URI. 161 // 162 // 1) Google Cloud Storage files (JSON) are defined in the following form. 163 // `gs://bucket_name/object_name`. For more information on Cloud Storage URIs, 164 // please see https://cloud.google.com/storage/docs/reference-uris. 165 string uri = 1; 166 167 // For BigQuery inputs defines the columns that should be used for dimensions 168 // (including time and group ID). 169 BigqueryMapping bq_mapping = 2; 170} 171 172// A collection of data sources sent for processing. 173message DataSet { 174 option (google.api.resource) = { 175 type: "timeseriesinsights.googleapis.com/Dataset" 176 pattern: "projects/{project}/datasets/{dataset}" 177 pattern: "projects/{project}/locations/{location}/datasets/{dataset}" 178 }; 179 180 // DataSet state. 181 enum State { 182 // Unspecified / undefined state. 183 STATE_UNSPECIFIED = 0; 184 185 // Dataset is unknown to the system; we have never seen this dataset before 186 // or we have seen this dataset but have fully GC-ed it. 187 UNKNOWN = 1; 188 189 // Dataset processing is pending. 190 PENDING = 2; 191 192 // Dataset is loading. 193 LOADING = 3; 194 195 // Dataset is loaded and can be queried. 196 LOADED = 4; 197 198 // Dataset is unloading. 199 UNLOADING = 5; 200 201 // Dataset is unloaded and is removed from the system. 202 UNLOADED = 6; 203 204 // Dataset processing failed. 205 FAILED = 7; 206 } 207 208 // The dataset name, which will be used for querying, status and unload 209 // requests. This must be unique within a project. 210 string name = 1; 211 212 // [Data dimension names][google.cloud.timeseriesinsights.v1.EventDimension.name] allowed for this `DataSet`. 213 // 214 // If left empty, all dimension names are included. This field works as a 215 // filter to avoid regenerating the data. 216 repeated string data_names = 2; 217 218 // Input data. 219 repeated DataSource data_sources = 3; 220 221 // Dataset state in the system. 222 State state = 4; 223 224 // Dataset processing status. 225 google.rpc.Status status = 5; 226 227 // Periodically we discard dataset [Event][google.cloud.timeseriesinsights.v1.Event] objects that have 228 // timestamps older than 'ttl'. Omitting this field or a zero value means no 229 // events are discarded. 230 google.protobuf.Duration ttl = 6; 231} 232 233// Represents an event dimension. 234message EventDimension { 235 // Dimension name. 236 // 237 // **NOTE**: `EventDimension` names must be composed of alphanumeric 238 // characters only, and are case insensitive. Unicode characters are *not* 239 // supported. The underscore '_' is also allowed. 240 string name = 1; 241 242 // Dimension value. 243 // 244 // **NOTE**: All entries of the dimension `name` must have the same `value` 245 // type. 246 oneof value { 247 // String representation. 248 // 249 // **NOTE**: String values are case insensitive. Unicode characters are 250 // supported. 251 string string_val = 2; 252 253 // Long representation. 254 int64 long_val = 3; 255 256 // Bool representation. 257 bool bool_val = 4; 258 259 // Double representation. 260 double double_val = 5; 261 } 262} 263 264// Represents an entry in a data source. 265// 266// Each Event has: 267// 268// * A timestamp at which the event occurs. 269// * One or multiple dimensions. 270// * Optionally, a group ID that allows clients to group logically related 271// events (for example, all events representing payments transactions done by 272// a user in a day have the same group ID). If a group ID is not provided, an 273// internal one will be generated based on the content and `eventTime`. 274// 275// **NOTE**: 276// 277// * Internally, we discretize time in equal-sized chunks and we assume an 278// event has a 0 279// [TimeseriesPoint.value][google.cloud.timeseriesinsights.v1.TimeseriesPoint.value] 280// in a chunk that does not contain any occurrences of an event in the input. 281// * The number of Events with the same group ID should be limited. 282// * Group ID *cannot* be queried. 283// * Group ID does *not* correspond to a user ID or the like. If a user ID is of 284// interest to be queried, use a user ID `dimension` instead. 285message Event { 286 // Event dimensions. 287 repeated EventDimension dimensions = 1; 288 289 // Event group ID. 290 // 291 // **NOTE**: JSON encoding should use a string to hold a 64-bit integer value, 292 // because a native JSON number holds only 53 binary bits for an integer. 293 int64 group_id = 2; 294 295 // Event timestamp. 296 google.protobuf.Timestamp event_time = 3; 297} 298 299// Appends events to an existing DataSet. 300message AppendEventsRequest { 301 // Events to be appended. 302 // 303 // Note: 304 // 305 // 0. The [DataSet][google.cloud.timeseriesinsights.v1.DataSet] must be shown in a `LOADED` state 306 // in the results of `list` method; otherwise, all events from 307 // the append request will be dropped, and a `NOT_FOUND` status will be 308 // returned. 309 // 0. All events in a single request must have the same 310 // [groupId][google.cloud.timeseriesinsights.v1.Event.group_id] if set; otherwise, an 311 // `INVALID_ARGUMENT` status will be returned. 312 // 0. If [groupId][google.cloud.timeseriesinsights.v1.Event.group_id] is not set (or 0), there 313 // should be only 1 event; otherwise, an `INVALID_ARGUMENT` status will be 314 // returned. 315 // 0. The events must be newer than the current time minus 316 // [DataSet TTL][google.cloud.timeseriesinsights.v1.DataSet.ttl] or they will be dropped. 317 repeated Event events = 1; 318 319 // Required. The DataSet to which we want to append to in the format of 320 // "projects/{project}/datasets/{dataset}" 321 string dataset = 2 [ 322 (google.api.field_behavior) = REQUIRED, 323 (google.api.resource_reference) = { 324 type: "timeseriesinsights.googleapis.com/Dataset" 325 } 326 ]; 327} 328 329// Response for an AppendEvents RPC. 330message AppendEventsResponse { 331 // Dropped events; empty if all events are successfully added. 332 repeated Event dropped_events = 1; 333} 334 335// Create a DataSet request. 336message CreateDataSetRequest { 337 // Required. Client project name which will own this DataSet in the format of 338 // 'projects/{project}'. 339 string parent = 1 [ 340 (google.api.field_behavior) = REQUIRED, 341 (google.api.resource_reference) = { 342 type: "cloudresourcemanager.googleapis.com/Project" 343 } 344 ]; 345 346 // Required. Dataset to be loaded. 347 DataSet dataset = 2 [(google.api.field_behavior) = REQUIRED]; 348} 349 350// Unload DataSet request from the serving system. 351message DeleteDataSetRequest { 352 // Required. Dataset name in the format of "projects/{project}/datasets/{dataset}" 353 string name = 1 [ 354 (google.api.field_behavior) = REQUIRED, 355 (google.api.resource_reference) = { 356 type: "timeseriesinsights.googleapis.com/Dataset" 357 } 358 ]; 359} 360 361// List the DataSets created by the current project. 362message ListDataSetsRequest { 363 // Required. Project owning the DataSet in the format of "projects/{project}". 364 string parent = 1 [ 365 (google.api.field_behavior) = REQUIRED, 366 (google.api.resource_reference) = { 367 type: "cloudresourcemanager.googleapis.com/Project" 368 } 369 ]; 370 371 // Number of results to return in the list. 372 int32 page_size = 2; 373 374 // Token to provide to skip to a particular spot in the list. 375 string page_token = 3; 376} 377 378// Created DataSets list response. 379message ListDataSetsResponse { 380 // The list of created DataSets. 381 repeated DataSet datasets = 1; 382 383 // Token to receive the next page of results. 384 string next_page_token = 2; 385} 386 387// A categorical dimension fixed to a certain value. 388message PinnedDimension { 389 // The name of the dimension for which we are fixing its value. 390 string name = 1; 391 392 // Dimension value. 393 // 394 // **NOTE**: The `value` type must match that in the data with the same 395 // `dimension` as name. 396 oneof value { 397 // A string value. This can be used for [dimensions][google.cloud.timeseriesinsights.v1.EventDimension], which 398 // have their value field set to [string_val][google.cloud.timeseriesinsights.v1.EventDimension.string_val]. 399 string string_val = 2; 400 401 // A bool value. This can be used for [dimensions][google.cloud.timeseriesinsights.v1.EventDimension], which 402 // have their value field set to [bool_val][google.cloud.timeseriesinsights.v1.EventDimension.bool_val]. 403 bool bool_val = 3; 404 } 405} 406 407// Parameters that control the sensitivity and other options for the time series 408// forecast. 409message ForecastParams { 410 // A time period of a fixed interval. 411 enum Period { 412 // Unknown or simply not given. 413 PERIOD_UNSPECIFIED = 0; 414 415 // 1 hour 416 HOURLY = 5; 417 418 // 24 hours 419 DAILY = 1; 420 421 // 7 days 422 WEEKLY = 2; 423 424 // 30 days 425 MONTHLY = 3; 426 427 // 365 days 428 YEARLY = 4; 429 } 430 431 // Optional. Penalize variations between the actual and forecasted values smaller than 432 // this. For more information about how this parameter affects the score, see 433 // the [anomalyScore](EvaluatedSlice.anomaly_score) formula. 434 // 435 // Intuitively, anomaly scores summarize how statistically significant the 436 // change between the actual and forecasted value is compared with what we 437 // expect the change to be (see 438 // [expectedDeviation](EvaluatedSlice.expected_deviation)). However, in 439 // practice, depending on the application, changes smaller than certain 440 // absolute values, while statistically significant, may not be important. 441 // 442 // This parameter allows us to penalize such low absolute value changes. 443 // 444 // Must be in the (0.0, inf) range. 445 // 446 // If unspecified, it defaults to 0.000001. 447 optional double noise_threshold = 12 [(google.api.field_behavior) = OPTIONAL]; 448 449 // Optional. Specifying any known seasonality/periodicity in the time series 450 // for the slices we will analyze can improve the quality of the results. 451 // 452 // If unsure, simply leave it unspecified by not setting a value for this 453 // field. 454 // 455 // If your time series has multiple seasonal patterns, then set it to the most 456 // granular one (e.g. if it has daily and weekly patterns, set this to DAILY). 457 Period seasonality_hint = 10 [(google.api.field_behavior) = OPTIONAL]; 458 459 // Optional. The length of the returned [forecasted 460 // timeseries][EvaluatedSlice.forecast]. 461 // 462 // This duration is currently capped at 100 x 463 // [granularity][google.cloud.timeseriesinsights.v1.TimeseriesParams.granularity]. 464 // 465 // Example: If the detection point is set to "2020-12-27T00:00:00Z", the 466 // [granularity][google.cloud.timeseriesinsights.v1.TimeseriesParams.granularity] to "3600s" and the 467 // horizon_duration to "10800s", then we will generate 3 time 468 // series points (from "2020-12-27T01:00:00Z" to "2020-12-27T04:00:00Z"), for 469 // which we will return their forecasted values. 470 // 471 // Note: The horizon time is only used for forecasting not for anormaly 472 // detection. To detect anomalies for multiple points of time, 473 // simply send multiple queries with those as 474 // [detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time]. 475 google.protobuf.Duration horizon_duration = 13 [(google.api.field_behavior) = OPTIONAL]; 476} 477 478// A point in a time series. 479message TimeseriesPoint { 480 // The timestamp of this point. 481 google.protobuf.Timestamp time = 1; 482 483 // The value for this point. 484 // 485 // It is computed by aggregating all events in the associated slice that are 486 // in the `[time, time + granularity]` range (see 487 // [granularity][google.cloud.timeseriesinsights.v1.TimeseriesParams.granularity]) using the specified 488 // [metric][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric]. 489 optional double value = 2; 490} 491 492// A time series. 493message Timeseries { 494 // The points in this time series, ordered by their timestamp. 495 repeated TimeseriesPoint point = 1; 496} 497 498// Forecast result for a given slice. 499message EvaluatedSlice { 500 // Values for all categorical dimensions that uniquely identify this slice. 501 repeated PinnedDimension dimensions = 1; 502 503 // The actual value at the detection time (see 504 // [detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time]). 505 // 506 // **NOTE**: This value can be an estimate, so it should not be used as a 507 // source of truth. 508 optional double detection_point_actual = 11; 509 510 // The expected value at the detection time, which is obtained by forecasting 511 // on the historical time series. 512 optional double detection_point_forecast = 12; 513 514 // How much our forecast model expects the detection point actual will 515 // deviate from its forecasted value based on how well it fit the input time 516 // series. 517 // 518 // In general, we expect the `detectionPointActual` to 519 // be in the `[detectionPointForecast - expectedDeviation, 520 // detectionPointForecast + expectedDeviation]` range. The more the actual 521 // value is outside this range, the more statistically significant the 522 // anomaly is. 523 // 524 // The expected deviation is always positive. 525 optional double expected_deviation = 16; 526 527 // Summarizes how significant the change between the actual and forecasted 528 // detection points are compared with the historical patterns observed on the 529 // [history][google.cloud.timeseriesinsights.v1.EvaluatedSlice.history] time series. 530 // 531 // Defined as *|a - f| / (e + nt)*, where: 532 // 533 // - *a* is the [detectionPointActual][google.cloud.timeseriesinsights.v1.EvaluatedSlice.detection_point_actual]. 534 // - *f* is the [detectionPointForecast][google.cloud.timeseriesinsights.v1.EvaluatedSlice.detection_point_forecast]. 535 // - *e* is the [expectedDeviation][google.cloud.timeseriesinsights.v1.EvaluatedSlice.expected_deviation]. 536 // - *nt` is the [noiseThreshold][google.cloud.timeseriesinsights.v1.ForecastParams.noise_threshold]. 537 // 538 // Anomaly scores between different requests and datasets are comparable. As 539 // a guideline, the risk of a slice being an anomaly based on the anomaly 540 // score is: 541 // 542 // - **Very High** if `anomalyScore` > 5. 543 // - **High** if the `anomalyScore` is in the [2, 5] range. 544 // - **Medium** if the `anomalyScore` is in the [1, 2) range. 545 // - **Low** if the `anomalyScore` is < 1. 546 // 547 // If there were issues evaluating this slice, then the anomaly score will be 548 // set to -1.0 and the [status][google.cloud.timeseriesinsights.v1.EvaluatedSlice.status] field will contain details on what 549 // went wrong. 550 optional double anomaly_score = 17; 551 552 // The actual values in the `[` 553 // [detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time] `-` 554 // [forecastHistory][google.cloud.timeseriesinsights.v1.TimeseriesParams.forecast_history]`,` 555 // [detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time] `]` time 556 // range. 557 // 558 // **NOTE**: This field is only populated if 559 // [returnTimeseries][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.return_timeseries] is true. 560 Timeseries history = 5; 561 562 // The forecasted values in the `[` 563 // [detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time] `+` 564 // [granularity][google.cloud.timeseriesinsights.v1.TimeseriesParams.granularity]`,` 565 // [forecastParams.horizonTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.forecast_params] `]` time 566 // range. 567 // 568 // **NOTE**: This field is only populated if 569 // [returnTimeseries][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.return_timeseries] is true. 570 Timeseries forecast = 10; 571 572 // Evaluation status. Contains an error message if the `anomalyScore` is < 0. 573 // 574 // Possible error messages: 575 // 576 // - **"Time series too sparse"**: The returned time series for this slice did 577 // not contain enough data points (we require a minimum of 10). 578 // - **"Not enough recent time series points"**: The time series contains the 579 // minimum of 10 points, but there are not enough close in time to the 580 // detection point. 581 // - **"Missing detection point data"**: There were not events to be 582 // aggregated within the `[detectionTime, detectionTime + granularity]` time 583 // interval, so we don't have an actual value with which we can compare our 584 // prediction. 585 // - **"Data retrieval error"**: We failed to retrieve the time series data 586 // for this slice and could not evaluate it successfully. Should be a 587 // transient error. 588 // - **"Internal server error"**: Internal unexpected error. 589 google.rpc.Status status = 18; 590} 591 592// Parameters that control how we slice the dataset and, optionally, filter 593// slices that have some specific values on some dimensions (pinned dimensions). 594message SlicingParams { 595 // Required. Dimensions over which we will group the events in slices. The names 596 // specified here come from the 597 // [EventDimension.name][google.cloud.timeseriesinsights.v1.EventDimension.name] field. At least 598 // one dimension name must be specified. All dimension names that do not exist 599 // in the queried `DataSet` will be ignored. 600 // 601 // Currently only dimensions that hold string values can be specified here. 602 repeated string dimension_names = 1 [(google.api.field_behavior) = REQUIRED]; 603 604 // Optional. We will only analyze slices for which 605 // [EvaluatedSlice.dimensions][google.cloud.timeseriesinsights.v1.EvaluatedSlice.dimensions] contain all of the 606 // following pinned dimensions. A query with a pinned dimension `{ name: "d3" 607 // stringVal: "v3" }` will only analyze events which contain the dimension `{ 608 // name: "d3" stringVal: "v3" }`. 609 // The [pinnedDimensions][google.cloud.timeseriesinsights.v1.SlicingParams.pinned_dimensions] and 610 // [dimensionNames][google.cloud.timeseriesinsights.v1.SlicingParams.dimension_names] fields can **not** 611 // share the same dimension names. 612 // 613 // Example a valid specification: 614 // 615 // ```json 616 // { 617 // dimensionNames: ["d1", "d2"], 618 // pinnedDimensions: [ 619 // { name: "d3" stringVal: "v3" }, 620 // { name: "d4" stringVal: "v4" } 621 // ] 622 // } 623 // ``` 624 // 625 // In the previous example we will slice the dataset by dimensions "d1", 626 // "d2", "d3" and "d4", but we will only analyze slices for which "d3=v3" and 627 // "d4=v4". 628 // 629 // The following example is **invalid** as "d2" is present in both 630 // dimensionNames and pinnedDimensions: 631 // 632 // ```json 633 // { 634 // dimensionNames: ["d1", "d2"], 635 // pinnedDimensions: [ 636 // { name: "d2" stringVal: "v2" }, 637 // { name: "d4" stringVal: "v4" } 638 // ] 639 // } 640 // ``` 641 repeated PinnedDimension pinned_dimensions = 2 [(google.api.field_behavior) = OPTIONAL]; 642} 643 644// Parameters that control how we construct the time series for each slice. 645message TimeseriesParams { 646 // Methods by which we can aggregate multiple events by a given 647 // [metric][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric]. 648 enum AggregationMethod { 649 // Unspecified. 650 AGGREGATION_METHOD_UNSPECIFIED = 0; 651 652 // Aggregate multiple events by summing up the values found in the 653 // [metric][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric] dimension. 654 SUM = 1; 655 656 // Aggregate multiple events by averaging out the values found in the 657 // [metric][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric] dimension. 658 AVERAGE = 2; 659 } 660 661 // Required. How long should we go in the past when fetching the timeline used for 662 // forecasting each slice. 663 // 664 // This is used in combination with the 665 // [detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time] parameter. 666 // The time series we construct will have the following time range: 667 // `[detectionTime - forecastHistory, detectionTime + granularity]`. 668 // 669 // The forecast history might be rounded up, so that a multiple of 670 // `granularity` is used to process the query. 671 // 672 // Note: If there are not enough events in the 673 // `[detectionTime - forecastHistory, detectionTime + granularity]` time 674 // interval, the slice evaluation can fail. For more information, see 675 // [EvaluatedSlice.status][google.cloud.timeseriesinsights.v1.EvaluatedSlice.status]. 676 google.protobuf.Duration forecast_history = 1 [(google.api.field_behavior) = REQUIRED]; 677 678 // Required. The time granularity of the time series (on the x-axis). Each time series 679 // point starting at time T will aggregate all events for a particular slice 680 // in *[T, T + granularity)* time windows. 681 // 682 // Note: The aggregation is decided based on the 683 // [metric][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric] parameter. 684 // 685 // This granularity defines the query-time aggregation windows and is not 686 // necessarily related to any event time granularity in the raw data (though 687 // we do recommend that the query-time granularity is not finer than the 688 // ingestion-time one). 689 // 690 // Currently, the minimal supported granularity is 10 seconds. 691 google.protobuf.Duration granularity = 2 [(google.api.field_behavior) = REQUIRED]; 692 693 // Optional. Denotes the [name][google.cloud.timeseriesinsights.v1.EventDimension.name] of a numerical 694 // dimension that will have its values aggregated to compute the y-axis of the 695 // time series. 696 // 697 // The aggregation method must also be specified by setting the 698 // [metricAggregationMethod][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric_aggregation_method] 699 // field. 700 // 701 // Note: Currently, if the aggregation method is unspecified, we will 702 // default to SUM for backward compatibility reasons, but new implementations 703 // should set the 704 // [metricAggregationMethod][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric_aggregation_method] 705 // explicitly. 706 // 707 // If the metric is unspecified, we will use the number of events that each 708 // time series point contains as the point value. 709 // 710 // Example: Let's assume we have the following three events in our dataset: 711 // ```json 712 // { 713 // eventTime: "2020-12-27T00:00:00Z", 714 // dimensions: [ 715 // { name: "d1" stringVal: "v1" }, 716 // { name: "d2" stringVal: "v2" } 717 // { name: "m1" longVal: 100 } 718 // { name: "m2" longVal: 11 } 719 // ] 720 // }, 721 // { 722 // eventTime: "2020-12-27T00:10:00Z", 723 // dimensions: [ 724 // { name: "d1" stringVal: "v1" }, 725 // { name: "d2" stringVal: "v2" } 726 // { name: "m1" longVal: 200 } 727 // { name: "m2" longVal: 22 } 728 // ] 729 // }, 730 // { 731 // eventTime: "2020-12-27T00:20:00Z", 732 // dimensions: [ 733 // { name: "d1" stringVal: "v1" }, 734 // { name: "d2" stringVal: "v2" } 735 // { name: "m1" longVal: 300 } 736 // { name: "m2" longVal: 33 } 737 // ] 738 // } 739 // ``` 740 // 741 // These events are all within the same hour, spaced 10 minutes between each 742 // of them. Assuming our [QueryDataSetRequest][google.cloud.timeseriesinsights.v1.QueryDataSetRequest] had set 743 // [slicingParams.dimensionNames][google.cloud.timeseriesinsights.v1.SlicingParams.dimension_names] to ["d1", 744 // "d2"] and [timeseries_params.granularity][google.cloud.timeseriesinsights.v1.TimeseriesParams.granularity] to 745 // "3600s", then all the previous events will be aggregated into the same 746 // [timeseries point][google.cloud.timeseriesinsights.v1.TimeseriesPoint]. 747 // 748 // The time series point that they're all part of will have the 749 // [time][google.cloud.timeseriesinsights.v1.TimeseriesPoint.time] set to "2020-12-27T00:00:00Z" and the 750 // [value][google.cloud.timeseriesinsights.v1.TimeseriesPoint.value] populated based on this metric field: 751 // 752 // - If the metric is set to "m1" and metric_aggregation_method to SUM, then 753 // the value of the point will be 600. 754 // - If the metric is set to "m2" and metric_aggregation_method to SUM, then 755 // the value of the point will be 66. 756 // - If the metric is set to "m1" and metric_aggregation_method to AVERAGE, 757 // then the value of the point will be 200. 758 // - If the metric is set to "m2" and metric_aggregation_method to AVERAGE, 759 // then the value of the point will be 22. 760 // - If the metric field is "" or unspecified, then the value of the point 761 // will be 3, as we will simply count the events. 762 optional string metric = 4 [(google.api.field_behavior) = OPTIONAL]; 763 764 // Optional. Together with the [metric][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric] field, specifies how 765 // we will aggregate multiple events to obtain the value of a time series 766 // point. See the [metric][google.cloud.timeseriesinsights.v1.TimeseriesParams.metric] documentation for more 767 // details. 768 // 769 // If the metric is not specified or "", then this field will be ignored. 770 AggregationMethod metric_aggregation_method = 5 [(google.api.field_behavior) = OPTIONAL]; 771} 772 773// Request for performing a query against a loaded DataSet. 774message QueryDataSetRequest { 775 // Required. Loaded DataSet to be queried in the format of 776 // "projects/{project}/datasets/{dataset}" 777 string name = 1 [ 778 (google.api.field_behavior) = REQUIRED, 779 (google.api.resource_reference) = { 780 type: "timeseriesinsights.googleapis.com/Dataset" 781 } 782 ]; 783 784 // Required. This is the point in time that we want to probe for anomalies. 785 // 786 // The corresponding [TimeseriesPoint][google.cloud.timeseriesinsights.v1.TimeseriesPoint] is referred to as the 787 // detection point. 788 // 789 // **NOTE**: As with any other time series point, the value is given by 790 // aggregating all events in the slice that are in the 791 // [detectionTime, detectionTime + granularity) time interval, where 792 // the granularity is specified in the 793 // [timeseriesParams.granularity][google.cloud.timeseriesinsights.v1.TimeseriesParams.granularity] field. 794 google.protobuf.Timestamp detection_time = 11 [(google.api.field_behavior) = REQUIRED]; 795 796 // How many slices are returned in 797 // [QueryDataSetResponse.slices][google.cloud.timeseriesinsights.v1.QueryDataSetResponse.slices]. 798 // 799 // The returned slices are tentatively the ones with the highest 800 // [anomaly scores][google.cloud.timeseriesinsights.v1.EvaluatedSlice.anomaly_score] in the dataset that match 801 // the query, but it is not guaranteed. 802 // 803 // Reducing this number will improve query performance, both in terms of 804 // latency and resource usage. 805 // 806 // Defaults to 50. 807 optional int32 num_returned_slices = 13; 808 809 // Parameters controlling how we will split the dataset into the slices that 810 // we will analyze. 811 SlicingParams slicing_params = 9; 812 813 // Parameters controlling how we will build the time series used to predict 814 // the [detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time] value for each slice. 815 TimeseriesParams timeseries_params = 10; 816 817 // Parameters that control the time series forecasting models, such as the 818 // sensitivity of the anomaly detection. 819 ForecastParams forecast_params = 5; 820 821 // If specified, we will return the actual and forecasted time for all 822 // returned slices. 823 // 824 // The time series are returned in the 825 // [EvaluatedSlice.history][google.cloud.timeseriesinsights.v1.EvaluatedSlice.history] and 826 // [EvaluatedSlice.forecast][google.cloud.timeseriesinsights.v1.EvaluatedSlice.forecast] fields. 827 bool return_timeseries = 8; 828} 829 830// Response for a query executed by the system. 831message QueryDataSetResponse { 832 // Loaded DataSet that was queried. 833 string name = 1; 834 835 // Slices sorted in descending order by their 836 // [anomalyScore][google.cloud.timeseriesinsights.v1.EvaluatedSlice.anomaly_score]. 837 // 838 // At most [numReturnedSlices][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.num_returned_slices] 839 // slices are present in this field. 840 repeated EvaluatedSlice slices = 3; 841} 842 843// Request for evaluateSlice. 844message EvaluateSliceRequest { 845 // Required. Loaded DataSet to be queried in the format of 846 // "projects/{project}/datasets/{dataset}" 847 string dataset = 1 [ 848 (google.api.field_behavior) = REQUIRED, 849 (google.api.resource_reference) = { 850 type: "timeseriesinsights.googleapis.com/Dataset" 851 } 852 ]; 853 854 // Required. Dimensions with pinned values that specify the slice for which we will 855 // fetch the time series. 856 repeated PinnedDimension pinned_dimensions = 2 [(google.api.field_behavior) = REQUIRED]; 857 858 // Required. This is the point in time that we want to probe for anomalies. 859 // 860 // See documentation for 861 // [QueryDataSetRequest.detectionTime][google.cloud.timeseriesinsights.v1.QueryDataSetRequest.detection_time]. 862 google.protobuf.Timestamp detection_time = 3 [(google.api.field_behavior) = REQUIRED]; 863 864 // Parameters controlling how we will build the time series used to predict 865 // the [detectionTime][google.cloud.timeseriesinsights.v1.EvaluateSliceRequest.detection_time] value for this slice. 866 TimeseriesParams timeseries_params = 4; 867 868 // Parameters that control the time series forecasting models, such as the 869 // sensitivity of the anomaly detection. 870 ForecastParams forecast_params = 5; 871} 872 873// Request for evaluateTimeseries. 874message EvaluateTimeseriesRequest { 875 // Required. Client project name in the format of 'projects/{project}'. 876 string parent = 1 [ 877 (google.api.field_behavior) = REQUIRED, 878 (google.api.resource_reference) = { 879 type: "cloudresourcemanager.googleapis.com/Project" 880 } 881 ]; 882 883 // Evaluate this time series without requiring it was previously loaded in 884 // a data set. 885 // 886 // The evaluated time series point is the last one, analogous to calling 887 // evaluateSlice or query with 888 // [detectionTime][google.cloud.timeseriesinsights.v1.EvaluateSliceRequest.detection_time] set to 889 // `timeseries.point(timeseries.point_size() - 1).time`. 890 // 891 // The length of the time series must be at least 10. 892 // 893 // All points must have the same time offset relative to the granularity. For 894 // example, if the [granularity][google.cloud.timeseriesinsights.v1.EvaluateTimeseriesRequest.granularity] is "5s", then the following 895 // point.time sequences are valid: 896 // - "100s", "105s", "120s", "125s" (no offset) 897 // - "102s", "107s", "122s", "127s" (offset is "2s") 898 // However, the following sequence is invalid as it has inconsistent offsets: 899 // - "100s", "105s", "122s", "127s" (offsets are either "0s" or "2s") 900 Timeseries timeseries = 2; 901 902 // The granularity of the time series (time distance between two consecutive 903 // points). 904 google.protobuf.Duration granularity = 3; 905 906 // The forecast parameters. 907 ForecastParams forecast_params = 4; 908} 909