Datadog alarm based on multiple thresholds - alarm

I am struggling to see if this is at all possible. If I have 2 queries:
A: avg:metric_one{service:foo}.as_count()
B: avg:metric_two{service:foo}.as_count()
And a FUNC (a/b)*100
I'd like a simple alarm that triggers when:
FUNC < 70 && A > 10
However, there seems to not be any option to put 2 critiria in. Any advice?
Thanks

For this use case, create a Composite Monitor. With composites you can define your triggering conditions based on the combined status of multiple monitors.

Related

Lambda random long execution while running QLDB query

I have a lambda triggered by a SQS FIFO queue when there are messages on this queue. Basically this lambda is getting the message from the queue and connecting to QLDB through a VPC endpoint in order to run a simple SELECT query and a subsequent INSERT query. The table selected by the query has a index for the field used in the where condition.
Flow (all the services are running "inside" a VPC):
SQS -> Lambda -> VPC interface endpoint -> QLDB
Query SELECT:
SELECT FIELD1, FIELD2 FROM TABLE1 WHERE FIELD3 = "ABCDE"
Query INSERT:
INSERT INTO TABLE1 .....
This lambda is using a shared connection/session on QLDB and this is how I'm connecting to it.
import { QldbDriver, RetryConfig } from 'amazon-qldb-driver-nodejs'
let driverQldb: QldbDriver
const ledgerName = 'MyLedger'
export function connectQLDB(): QldbDriver {
if ( !driverQldb ) {
const retryLimit = 4
const retryConfig = new RetryConfig(retryLimit)
const maxConcurrentTransactions = 1500
driverQldb = new QldbDriver(ledgerName, {}, maxConcurrentTransactions, retryConfig)
}
return driverQldb
}
When I run a load test that simulates around 200 requests/messages per second to that lambda in a time interval of 15 minutes, I'm starting facing a random long execution for that lambda while running the queries on QLDB (mainly the SELECT query). Sometimes the same query retrieves data around 100ms and sometimes it takes more than 40 seconds which results in lambda timeouts. I have changed lambda timeout to 1 minute but this is not the best approch and sometimes it is not enough too.
The VPC endpoint metrics are showing around 250 active connections and 1000 new connections during this load test execution. Is there any QLDB metric that could help to identify the root cause of this behavior?
Could it be related to some QLDB limitation (like the 1500 active sessions described here: https://docs.aws.amazon.com/qldb/latest/developerguide/limits.html#limits.default) or something related to concurrency read/write iops?
scodeler, I've read through the NodeJS QLDB driver, and I think theres an order of operations error. If you provide your own backoff function in the RetryConfig where RetryConfig(4, newBackoffFunction), you should see significant performance improvement in your lambda's completing.
The driver's default backoff
const exponentialBackoff: number = Math.min(SLEEP_CAP_MS, Math.pow(SLEEP_BASE_MS * 2, retryAttempt));
summarized...it returns
return Math.random() * exponentialBackoff;
does not match the default best jitter function practices
const newBackoffFunction: BackoffFunction = (retryAttempt: number, error: Error, transactionId: string) => {
const exponentialBackoff: number = Math.min(SLEEP_CAP_MS, SLEEP_BASE_MS * Math.pow(2, retryAttempt));
const jitterRand: number = Math.random();
const delayTime: number = jitterRand * exponentialBackoff;
return delayTime;
}
The difference is that the SLEEP_BASE_MS should be multiplied by 2 ^ retryAttempt, and not (SLEEP_BASE_MS x 2) ^ retryAttempt.
Hope this helps!

Is there any way to monitor Azure Synapse Pipelines execution?

In my project, I've a need where I need to show how Pipeline is progressing on custom Web Portal built in PHP. Is there any way in any language such as C# or Java through which I can list pipelines and monitor the progress or even log into Application Insights?
Are you labelling your queries with the OPTION (LABEL='MY LABEL') syntax?
This will make it easy to monitor the progress of your pipeline by querying sys.dm_pdw_exec_requests to pick individual queries (see last paragraph under link heading), and if you use a naming convention like 'pipeline_query' you can probably achieve what you want.
try
{
PipelineRunClient pipelineRunClient = new(new Uri(_Settings.SynapseExtractEndpoint), new DefaultAzureCredential());
run = await pipelineRunClient.GetPipelineRunAsync(runId);
while(run.Status == "InProgress" || run.Status == "Queued")
{
_Logger.LogInformation($"!!Pipeline {run.PipelineName} {runId} Status: {run.Status}");
Task.Delay(30000).Wait();
run = await pipelineRunClient.GetPipelineRunAsync(runId);
}
_Logger.LogInformation($"!!Pipeline {run.PipelineName} {runId} Status: {run.Status} Runtime: {run.DurationInMs} Message: {run.Message}");
}

Can a QFutureWatcher be used to monitor multiple serial tasks all run with QConcurrent?

I have a series of tasks that need to happen on a set of images. There are 3 steps which I want to run one after each other, but the middle one needs to be run serially because it relies on the results of all the previous iterations. What I want is to relay the progress of these three tasks back to the UI using a QFutureWatcher. I already have other tasks that do this and hook into progress bars etc, so kinda what to use the same process if I can. The way I'm thinking of implementing is to have an internal QFuture and QFutureWatcher that runs each task, and one external QFutureWatcher that monitors this an relays info to the UI. Maybe something like this (pseudo code):
runProcessingTask() {
connect(externalFutureWatcher, UI elements)
internalFuture = start first task
internalFutureWatcher.setFuture(internalFuture)
connect(internalFuture.finished(), taskfinished())
connect(internalFuture.progressValue(), updateProgress())
taskNumber = 1
}
taskFinished() {
switch(taskNumber):
case 1:
internalFuture = start second task
internalFutureWatcher.setFuture(internalFuture)
taskNumber = 2
case 2:
internalFuture = start third task
internalFutureWatcher.setFuture(internalFuture)
taskNumber = 3
case 3:
externalFutureWatcher.setFinished()
}
updateProgress() {
switch(taskNumber):
case 1:
extrenalFutureWatcher.setProgress(internalFutureWatcher.progress() / 3)
case 2:
extrenalFutureWatcher.setProgress(33.3% + (internalFutureWatcher.progress() / 3))
case 3:
extrenalFutureWatcher.setProgress(66.6% + (internalFutureWatcher.progress() / 3))
}
Would this sort of thing be possible? Do I just need to override some methods in QFutureWatcher and use them as my externalFutureWatcher? Or is it not possible in this way/ is there a much better way of doing this?

It is possible to detect unordered event patterns with WSO2?

I would like to detect some patterns using wso2, but my current solution is only capable to detect them if the events arrived are consecutives.
Let's suppose the following pattern:
Event 1: Scanning Event from Source 1 to Target 2
Event 2: Attempt Exploit from Source 1 to Target 2
That would generate an Alert.
But in a real world scenario, the events won't come in order, there are too many computers in an enterprise.
There is a way to be able to detect the previous pattern with the following event sequence?
Event 1: Scanning Event from Source 1 to Target 2
Event 2: Not relevant
Event 3: Not relevant
...
Event N: Attempt Exploit from Source 1 to Target 2
My Current code is:
from every (e1=Events) -> e2=Events
within 10 min
select ...
having e1.type=='Scan' and e2.type=='attack' and e1.Source_IP4==e2.Source_IP4
insert into Alert;
I've also tried other kind of solutions like
from every e1=Events,e2=Events[Condition]
within 10 min
select ...
having e1.type=='Scan' and e2.type=='attack' and e1.Source_IP4==e2.Source_IP4
insert into Alert;
Maybe it could be done with a Partition? Partiotionate the streams taking into account the Source_IP4
I've finally made it.
The problem was to use "having" to detect the pattern, It has to be moved to the "filter condition" section instead.
from (every)? <event reference>=<input stream>[<filter condition>] ->
(every)? <event reference>=<input stream [<filter condition>] ->
...
(within <time gap>)?
select <event reference>.<attribute name>, <event reference>.<attribute name>, ...
insert into <output stream>
Solution:
from every (e1=Events) -> e2=Events[e1.type=='Scan' and type=='attack' and e1.Source_IP4==Source_IP4]
within 10 min
select ...
insert into Alert;

Observable defer in Akka Streams

I´m coming from ReactiveX and there we have the operator defer, in order to create an Observable and get the emission value once we have a subscriber.
Here in Akka Streams I was wondering if something like that exists:
#Test def defer(): Unit = {
var range = 0 to 10
val graphs = Source(range)
.to(Sink.foreach(println))
range = 10 to 20
graphs.run()
Thread.sleep(2000)
}
Having this code, even before we execute run(), changing the value of the range, the value is not changed since the blueprint is already created, and emits 0 to 10.
Is anything like Observable.defer in Akka Streams?
SOLUTION:
I found the solution, the solution is using lazy keyword, where we provide a function which to be executed once we run the stream.
I will keep the question just in case there´s a better way or someone else has the same question
#Test def defer(): Unit = {
var range = 0 to 10
val graphs = Source.lazily(() => Source(range))
.to(Sink.foreach(println))
range = 10 to 20
graphs.run()
Thread.sleep(2000)
}
Regards.
The simplest way would probably be Source.fromIterator(() => List(1).iterator) or something similar. In the Akka Streams API we opted to try to keep the minimal set of operators, so sometimes you may get into situations where the same is achievable in an one-liner, but would not have a direct counterpart with a name like in defer's case here. If you think it's a common enough thing please let us know on github.com/akka/akka and we could consider adding it as an API.
Note that there's also fromFuture and other ones, which while not directly related may be useful depending on your actual use-case (esp. when combined with a Promise etc).