Skip to content
Draft

Ppl #1925

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e7a4685
CreateMonitorV2 RestHandler
toepkerd-zz Aug 4, 2025
0de50e6
CreatePPLMonitor Transport
toepkerd-zz Aug 11, 2025
c990c03
ExecutePPLMonitor with NumResults Trigger Implementation
toepkerd-zz Aug 16, 2025
8074501
DeletePPLMonitor initial implementation
toepkerd-zz Aug 18, 2025
55ad56f
Adding time filtering to monitor execution queries
toepkerd-zz Aug 20, 2025
89f8bde
initial implementation of custom trigger conditions
toepkerd-zz Aug 21, 2025
23024ee
initial implementation of per result triggers
toepkerd-zz Aug 21, 2025
9594b0a
alert suppression, expiration, and some run monitor refactors
toepkerd-zz Aug 26, 2025
2fe4279
refactors and initial result set notifications implementation
toepkerd-zz Aug 27, 2025
7a655d4
initial implementation of notifications integration
toepkerd-zz Aug 29, 2025
264c51a
initial implementations of GetMonitor, UpdateMonitor, MonitorStats
toepkerd-zz Sep 3, 2025
9870202
misc cleanup
toepkerd-zz Sep 3, 2025
e748065
update monitor and lookback window implementations
toepkerd-zz Sep 4, 2025
6fb26e8
per results notifications
toepkerd-zz Sep 5, 2025
6eed1cd
alert generation refactors
toepkerd-zz Sep 6, 2025
dc5f445
cleaning up based on deleted AlertV2 fields
toepkerd-zz Sep 6, 2025
2f9974c
various cleanup
toepkerd-zz Sep 8, 2025
2f57c5c
removing execute monitor actions to move to common utils, add to aler…
toepkerd-zz Sep 8, 2025
7b6d90d
adding executionId to alert generations
toepkerd-zz Sep 8, 2025
a66165c
misc cleanup
toepkerd-zz Sep 8, 2025
f1b4c37
more misc cleanup
toepkerd-zz Sep 8, 2025
b9fc041
removing unused import
toepkerd-zz Sep 8, 2025
c270057
moving all common utils models and dependencies to alerting
toepkerd-zz Sep 10, 2025
45f9250
moving nonOptionalTimeField function from common utils to alerting
toepkerd-zz Sep 10, 2025
ad9b57e
adding PPL Monitor query validations before creating PPL Monitors
toepkerd-zz Sep 11, 2025
9130713
initial alert v2 history implementation
toepkerd-zz Sep 12, 2025
97ebe37
cleaning up build.gradle
toepkerd-zz Sep 12, 2025
bb73e22
more cleanup
toepkerd-zz Sep 12, 2025
99bc75b
more cleanup
toepkerd-zz Sep 12, 2025
6a054f6
gave AlertV2s their own index and history indices and rewired Get Ale…
toepkerd-zz Sep 13, 2025
3646931
initial create/update rbac implementation
toepkerd-zz Sep 15, 2025
53afc6c
removing requirement for lookback to be for cron only
toepkerd-zz Sep 16, 2025
25ca4da
initial rbac implementation and alerting v2 doesnt affect alerting v1…
toepkerd-zz Sep 18, 2025
50b570f
separate alerting v1 and v2
toepkerd-zz Sep 19, 2025
d457ba8
misc rbac bug fixes
toepkerd-zz Sep 19, 2025
e505e12
removing query results from alert
toepkerd-zz Sep 23, 2025
19bc2dc
now checks query results size and truncates before passing into notif…
toepkerd-zz Sep 23, 2025
6093ad0
refactored limiting the number of alerts from a per_result trigger
toepkerd-zz Sep 25, 2025
e3e1832
manually calling execute monitor API should no longer get suppressed
toepkerd-zz Sep 25, 2025
7366e00
deploy cleanup
toepkerd-zz Sep 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions alerting/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,10 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:${kotlin_version}"
implementation "org.jetbrains:annotations:13.0"

// SQL/PPL plugin dependencies are included in alerting-core
api project(":alerting-core")
implementation 'org.json:json:20240303'

implementation "com.github.seancfoley:ipaddress:5.4.1"
implementation project(path: ":alerting-spi", configuration: 'shadow')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,26 @@ import org.opensearch.alerting.action.GetEmailGroupAction
import org.opensearch.alerting.action.GetRemoteIndexesAction
import org.opensearch.alerting.action.SearchEmailAccountAction
import org.opensearch.alerting.action.SearchEmailGroupAction
import org.opensearch.alerting.actionv2.DeleteMonitorV2Action
import org.opensearch.alerting.actionv2.ExecuteMonitorV2Action
import org.opensearch.alerting.actionv2.GetAlertsV2Action
import org.opensearch.alerting.actionv2.GetMonitorV2Action
import org.opensearch.alerting.actionv2.IndexMonitorV2Action
import org.opensearch.alerting.actionv2.SearchMonitorV2Action
import org.opensearch.alerting.alerts.AlertIndices
import org.opensearch.alerting.alerts.AlertIndices.Companion.ALL_ALERT_INDEX_PATTERN
import org.opensearch.alerting.alertsv2.AlertV2Indices
import org.opensearch.alerting.alertsv2.AlertV2Mover
import org.opensearch.alerting.comments.CommentsIndices
import org.opensearch.alerting.comments.CommentsIndices.Companion.ALL_COMMENTS_INDEX_PATTERN
import org.opensearch.alerting.core.JobSweeper
import org.opensearch.alerting.core.ScheduledJobIndices
import org.opensearch.alerting.core.action.node.ScheduledJobsStatsAction
import org.opensearch.alerting.core.action.node.ScheduledJobsStatsTransportAction
import org.opensearch.alerting.core.lock.LockService
import org.opensearch.alerting.core.modelv2.MonitorV2
import org.opensearch.alerting.core.resthandler.RestScheduledJobStatsHandler
import org.opensearch.alerting.core.resthandler.RestScheduledJobStatsV2Handler
import org.opensearch.alerting.core.schedule.JobScheduler
import org.opensearch.alerting.core.settings.LegacyOpenDistroScheduledJobSettings
import org.opensearch.alerting.core.settings.ScheduledJobSettings
Expand All @@ -32,25 +42,31 @@ import org.opensearch.alerting.resthandler.RestAcknowledgeAlertAction
import org.opensearch.alerting.resthandler.RestAcknowledgeChainedAlertAction
import org.opensearch.alerting.resthandler.RestDeleteAlertingCommentAction
import org.opensearch.alerting.resthandler.RestDeleteMonitorAction
import org.opensearch.alerting.resthandler.RestDeleteMonitorV2Action
import org.opensearch.alerting.resthandler.RestDeleteWorkflowAction
import org.opensearch.alerting.resthandler.RestExecuteMonitorAction
import org.opensearch.alerting.resthandler.RestExecuteMonitorV2Action
import org.opensearch.alerting.resthandler.RestExecuteWorkflowAction
import org.opensearch.alerting.resthandler.RestGetAlertsAction
import org.opensearch.alerting.resthandler.RestGetAlertsV2Action
import org.opensearch.alerting.resthandler.RestGetDestinationsAction
import org.opensearch.alerting.resthandler.RestGetEmailAccountAction
import org.opensearch.alerting.resthandler.RestGetEmailGroupAction
import org.opensearch.alerting.resthandler.RestGetFindingsAction
import org.opensearch.alerting.resthandler.RestGetMonitorAction
import org.opensearch.alerting.resthandler.RestGetMonitorV2Action
import org.opensearch.alerting.resthandler.RestGetRemoteIndexesAction
import org.opensearch.alerting.resthandler.RestGetWorkflowAction
import org.opensearch.alerting.resthandler.RestGetWorkflowAlertsAction
import org.opensearch.alerting.resthandler.RestIndexAlertingCommentAction
import org.opensearch.alerting.resthandler.RestIndexMonitorAction
import org.opensearch.alerting.resthandler.RestIndexMonitorV2Action
import org.opensearch.alerting.resthandler.RestIndexWorkflowAction
import org.opensearch.alerting.resthandler.RestSearchAlertingCommentAction
import org.opensearch.alerting.resthandler.RestSearchEmailAccountAction
import org.opensearch.alerting.resthandler.RestSearchEmailGroupAction
import org.opensearch.alerting.resthandler.RestSearchMonitorAction
import org.opensearch.alerting.resthandler.RestSearchMonitorV2Action
import org.opensearch.alerting.script.TriggerScript
import org.opensearch.alerting.service.DeleteMonitorService
import org.opensearch.alerting.settings.AlertingSettings
Expand All @@ -63,26 +79,32 @@ import org.opensearch.alerting.transport.TransportAcknowledgeAlertAction
import org.opensearch.alerting.transport.TransportAcknowledgeChainedAlertAction
import org.opensearch.alerting.transport.TransportDeleteAlertingCommentAction
import org.opensearch.alerting.transport.TransportDeleteMonitorAction
import org.opensearch.alerting.transport.TransportDeleteMonitorV2Action
import org.opensearch.alerting.transport.TransportDeleteWorkflowAction
import org.opensearch.alerting.transport.TransportDocLevelMonitorFanOutAction
import org.opensearch.alerting.transport.TransportExecuteMonitorAction
import org.opensearch.alerting.transport.TransportExecuteMonitorV2Action
import org.opensearch.alerting.transport.TransportExecuteWorkflowAction
import org.opensearch.alerting.transport.TransportGetAlertsAction
import org.opensearch.alerting.transport.TransportGetAlertsV2Action
import org.opensearch.alerting.transport.TransportGetDestinationsAction
import org.opensearch.alerting.transport.TransportGetEmailAccountAction
import org.opensearch.alerting.transport.TransportGetEmailGroupAction
import org.opensearch.alerting.transport.TransportGetFindingsSearchAction
import org.opensearch.alerting.transport.TransportGetMonitorAction
import org.opensearch.alerting.transport.TransportGetMonitorV2Action
import org.opensearch.alerting.transport.TransportGetRemoteIndexesAction
import org.opensearch.alerting.transport.TransportGetWorkflowAction
import org.opensearch.alerting.transport.TransportGetWorkflowAlertsAction
import org.opensearch.alerting.transport.TransportIndexAlertingCommentAction
import org.opensearch.alerting.transport.TransportIndexMonitorAction
import org.opensearch.alerting.transport.TransportIndexMonitorV2Action
import org.opensearch.alerting.transport.TransportIndexWorkflowAction
import org.opensearch.alerting.transport.TransportSearchAlertingCommentAction
import org.opensearch.alerting.transport.TransportSearchEmailAccountAction
import org.opensearch.alerting.transport.TransportSearchEmailGroupAction
import org.opensearch.alerting.transport.TransportSearchMonitorAction
import org.opensearch.alerting.transport.TransportSearchMonitorV2Action
import org.opensearch.alerting.util.DocLevelMonitorQueries
import org.opensearch.alerting.util.destinationmigration.DestinationMigrationCoordinator
import org.opensearch.cluster.metadata.IndexNameExpressionResolver
Expand Down Expand Up @@ -157,6 +179,7 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
@JvmField val OPEN_SEARCH_DASHBOARDS_USER_AGENT = "OpenSearch-Dashboards"
@JvmField val UI_METADATA_EXCLUDE = arrayOf("monitor.${Monitor.UI_METADATA_FIELD}")
@JvmField val MONITOR_BASE_URI = "/_plugins/_alerting/monitors"
@JvmField val MONITOR_V2_BASE_URI = "/_plugins/_alerting/v2/monitors"
@JvmField val WORKFLOW_BASE_URI = "/_plugins/_alerting/workflows"
@JvmField val REMOTE_BASE_URI = "/_plugins/_alerting/remote"
@JvmField val DESTINATION_BASE_URI = "/_plugins/_alerting/destinations"
Expand All @@ -169,7 +192,7 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
@JvmField val FINDING_BASE_URI = "/_plugins/_alerting/findings"
@JvmField val COMMENTS_BASE_URI = "/_plugins/_alerting/comments"

@JvmField val ALERTING_JOB_TYPES = listOf("monitor", "workflow")
@JvmField val ALERTING_JOB_TYPES = listOf("monitor", "workflow", "monitor_v2")
}

lateinit var runner: MonitorRunnerService
Expand All @@ -180,8 +203,10 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
lateinit var docLevelMonitorQueries: DocLevelMonitorQueries
lateinit var threadPool: ThreadPool
lateinit var alertIndices: AlertIndices
lateinit var alertV2Indices: AlertV2Indices
lateinit var clusterService: ClusterService
lateinit var destinationMigrationCoordinator: DestinationMigrationCoordinator
lateinit var alertV2Mover: AlertV2Mover
var monitorTypeToMonitorRunners: MutableMap<String, RemoteMonitorRegistry> = mutableMapOf()

override fun getRestHandlers(
Expand All @@ -194,6 +219,7 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
nodesInCluster: Supplier<DiscoveryNodes>
): List<RestHandler> {
return listOf(
// Alerting V1
RestGetMonitorAction(),
RestDeleteMonitorAction(),
RestIndexMonitorAction(),
Expand All @@ -218,11 +244,21 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
RestIndexAlertingCommentAction(),
RestSearchAlertingCommentAction(),
RestDeleteAlertingCommentAction(),

// Alerting V2
RestIndexMonitorV2Action(),
RestExecuteMonitorV2Action(),
RestDeleteMonitorV2Action(),
RestGetMonitorV2Action(),
RestSearchMonitorV2Action(settings, clusterService),
RestGetAlertsV2Action(),
RestScheduledJobStatsV2Handler()
)
}

override fun getActions(): List<ActionPlugin.ActionHandler<out ActionRequest, out ActionResponse>> {
return listOf(
// Alerting V1
ActionPlugin.ActionHandler(ScheduledJobsStatsAction.INSTANCE, ScheduledJobsStatsTransportAction::class.java),
ActionPlugin.ActionHandler(AlertingActions.INDEX_MONITOR_ACTION_TYPE, TransportIndexMonitorAction::class.java),
ActionPlugin.ActionHandler(AlertingActions.GET_MONITOR_ACTION_TYPE, TransportGetMonitorAction::class.java),
Expand All @@ -249,13 +285,22 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
ActionPlugin.ActionHandler(AlertingActions.DELETE_COMMENT_ACTION_TYPE, TransportDeleteAlertingCommentAction::class.java),
ActionPlugin.ActionHandler(ExecuteWorkflowAction.INSTANCE, TransportExecuteWorkflowAction::class.java),
ActionPlugin.ActionHandler(GetRemoteIndexesAction.INSTANCE, TransportGetRemoteIndexesAction::class.java),
ActionPlugin.ActionHandler(DocLevelMonitorFanOutAction.INSTANCE, TransportDocLevelMonitorFanOutAction::class.java)
ActionPlugin.ActionHandler(DocLevelMonitorFanOutAction.INSTANCE, TransportDocLevelMonitorFanOutAction::class.java),

// Alerting V2
ActionPlugin.ActionHandler(IndexMonitorV2Action.INSTANCE, TransportIndexMonitorV2Action::class.java),
ActionPlugin.ActionHandler(GetMonitorV2Action.INSTANCE, TransportGetMonitorV2Action::class.java),
ActionPlugin.ActionHandler(SearchMonitorV2Action.INSTANCE, TransportSearchMonitorV2Action::class.java),
ActionPlugin.ActionHandler(DeleteMonitorV2Action.INSTANCE, TransportDeleteMonitorV2Action::class.java),
ActionPlugin.ActionHandler(ExecuteMonitorV2Action.INSTANCE, TransportExecuteMonitorV2Action::class.java),
ActionPlugin.ActionHandler(GetAlertsV2Action.INSTANCE, TransportGetAlertsV2Action::class.java)
)
}

override fun getNamedXContent(): List<NamedXContentRegistry.Entry> {
return listOf(
Monitor.XCONTENT_REGISTRY,
MonitorV2.XCONTENT_REGISTRY,
SearchInput.XCONTENT_REGISTRY,
DocLevelMonitorInput.XCONTENT_REGISTRY,
QueryLevelTrigger.XCONTENT_REGISTRY,
Expand Down Expand Up @@ -285,6 +330,7 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
val settings = environment.settings()
val lockService = LockService(client, clusterService)
alertIndices = AlertIndices(settings, client, threadPool, clusterService)
alertV2Indices = AlertV2Indices(settings, client, threadPool, clusterService)
val alertService = AlertService(client, xContentRegistry, alertIndices)
val triggerService = TriggerService(scriptService)
runner = MonitorRunnerService
Expand All @@ -296,6 +342,7 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
.registerSettings(settings)
.registerThreadPool(threadPool)
.registerAlertIndices(alertIndices)
.registerAlertV2Indices(alertV2Indices)
.registerInputService(
InputService(
client,
Expand All @@ -322,6 +369,7 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
scheduler = JobScheduler(threadPool, runner)
sweeper = JobSweeper(environment.settings(), client, clusterService, threadPool, xContentRegistry, scheduler, ALERTING_JOB_TYPES)
destinationMigrationCoordinator = DestinationMigrationCoordinator(client, clusterService, threadPool, scheduledJobIndices)
alertV2Mover = AlertV2Mover(environment.settings(), client, threadPool, clusterService)
this.threadPool = threadPool
this.clusterService = clusterService

Expand Down Expand Up @@ -349,6 +397,7 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
commentsIndices,
docLevelMonitorQueries,
destinationMigrationCoordinator,
alertV2Mover,
lockService,
alertService,
triggerService
Expand Down Expand Up @@ -431,7 +480,14 @@ internal class AlertingPlugin : PainlessExtension, ActionPlugin, ScriptPlugin, R
AlertingSettings.COMMENTS_HISTORY_RETENTION_PERIOD,
AlertingSettings.COMMENTS_MAX_CONTENT_SIZE,
AlertingSettings.MAX_COMMENTS_PER_ALERT,
AlertingSettings.MAX_COMMENTS_PER_NOTIFICATION
AlertingSettings.MAX_COMMENTS_PER_NOTIFICATION,
AlertingSettings.ALERT_V2_HISTORY_ENABLED,
AlertingSettings.ALERT_V2_HISTORY_ROLLOVER_PERIOD,
AlertingSettings.ALERT_V2_HISTORY_INDEX_MAX_AGE,
AlertingSettings.ALERT_V2_HISTORY_MAX_DOCS,
AlertingSettings.ALERT_V2_HISTORY_RETENTION_PERIOD,
AlertingSettings.ALERT_V2_NOTIF_QUERY_RESULTS_MAX_SIZE,
AlertingSettings.ALERT_V2_PER_RESULT_TRIGGER_MAX_ALERTS
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.opensearch.alerting

import org.opensearch.alerting.core.modelv2.MonitorV2
import org.opensearch.commons.alerting.model.Monitor
import org.opensearch.commons.alerting.model.ScheduledJob

object AlertingV2Utils {

// Validates that the given scheduled job is a Monitor
// returns the exception to pass into actionListener.onFailure if not.
fun validateMonitorV1(scheduledJob: ScheduledJob): Exception? {
if (scheduledJob is MonitorV2) {
return IllegalArgumentException("The ID given corresponds to a V2 Monitor, please pass in the ID of a V1 Monitor")
} else if (scheduledJob !is Monitor) {
return IllegalArgumentException("The ID given corresponds to a scheduled job of unknown type: ${scheduledJob.javaClass.name}")
}
return null
}

// Validates that the given scheduled job is a MonitorV2
// returns the exception to pass into actionListener.onFailure if not.
fun validateMonitorV2(scheduledJob: ScheduledJob): Exception? {
if (scheduledJob is Monitor) {
return IllegalArgumentException("The ID given corresponds to a V1 Monitor, please pass in the ID of a V2 Monitor")
} else if (scheduledJob !is MonitorV2) {
return IllegalArgumentException("The ID given corresponds to a scheduled job of unknown type: ${scheduledJob.javaClass.name}")
}
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ abstract class MonitorRunner {
}
}

protected suspend fun getConfigAndSendNotification(
suspend fun getConfigAndSendNotification(
action: Action,
monitorCtx: MonitorRunnerExecutionContext,
subject: String?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package org.opensearch.alerting

import org.opensearch.action.bulk.BackoffPolicy
import org.opensearch.alerting.alerts.AlertIndices
import org.opensearch.alerting.alertsv2.AlertV2Indices
import org.opensearch.alerting.core.lock.LockService
import org.opensearch.alerting.model.destination.DestinationContextFactory
import org.opensearch.alerting.remote.monitors.RemoteMonitorRegistry
Expand Down Expand Up @@ -35,6 +36,7 @@ data class MonitorRunnerExecutionContext(
var settings: Settings? = null,
var threadPool: ThreadPool? = null,
var alertIndices: AlertIndices? = null,
var alertV2Indices: AlertV2Indices? = null,
var inputService: InputService? = null,
var triggerService: TriggerService? = null,
var alertService: AlertService? = null,
Expand Down
Loading
Loading