Initializing prometheus counters to 0 whenever a new time series is created - counter

I am working on a use case in which new time series gets created whenever metrics are pushed. I am using counter for my metrics. And I am using sum(increase(metric_name{_namespace_="elvis", Label1=~"d1", Label2=~"d2", Label3=~"d3"}[2m])) by (Label1, Label2, Label3) But my counters are getting initialized to 1 and not 0 because of which when i use the above query, I am not able to see the jump in counter from 0 to 1. I tried to initialize my counters while registering it as shown below but it doesn't help. Any help would be greatly appreciated
SimpleCollector counter = metricsMap.get(metricName);
double cntrValue = 0d;
if (counter == null) {
synchronized (metricsMap) {
counter = metricsMap.get(metricName);
if (counter == null) {
counter = Counter.build()
.name(decorateMetricsName(metricName))
.help(decorateMetricsName(metricName) + " counter")
.register();
metricsMap.put(metricName, counter);
cntrValue = ((Counter) counter.labels(getLabelValues(labels))).get();
logger.info( "Manifested Time Series with value");
logger.info( "Registered " + metricName);
} else {
return (Counter)counter;
}
}
}

Related

Plc4x library Modbus serial (RTU) get is not retrieving data

I am trying to write a sample program to retrieve temperature data from SHT20 temperature sensor using serial port with apache plc4x library.
private void plcRtuReader() {
String connectionString =
"modbus:serial://COM5?unit-identifier=1&baudRate=19200&stopBits=" + SerialPort.ONE_STOP_BIT + "&parityBits=" + SerialPort.NO_PARITY + "&dataBits=8";
try (PlcConnection plcConnection = new PlcDriverManager().getConnection(connectionString)) {
if (!plcConnection.getMetadata().canRead()) {
System.out.println("This connection doesn't support reading.");
return;
}
PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
builder.addItem("value-1", "holding-register:258[2]");
PlcReadRequest readRequest = builder.build();
PlcReadResponse response = readRequest.execute().get();
for (String fieldName : response.getFieldNames()) {
if (response.getResponseCode(fieldName) == PlcResponseCode.OK) {
int numValues = response.getNumberOfValues(fieldName);
// If it's just one element, output just one single line.
if (numValues == 1) {
System.out.println("Value[" + fieldName + "]: " + response.getObject(fieldName));
}
// If it's more than one element, output each in a single row.
else {
System.out.println("Value[" + fieldName + "]:");
for (int i = 0; i < numValues; i++) {
System.out.println(" - " + response.getObject(fieldName, i));
}
}
}
// Something went wrong, to output an error message instead.
else {
System.out.println(
"Error[" + fieldName + "]: " + response.getResponseCode(fieldName).name());
}
}
System.exit(0);
} catch (PlcConnectionException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Connection is established with the device using serial communication. But it fails to get data and instead prints the below warning messages continously.
debugger hangs at below line:
PlcReadResponse response = readRequest.execute().get();
with below logs printing continuously.
2021-06-03-17:41:48.425 [nioEventLoopGroup-2-1] WARN io.netty.channel.nio.NioEventLoop - Selector.select() returned prematurely 512 times in a row; rebuilding Selector org.apache.plc4x.java.transport.serial.SerialPollingSelector#131f8986.
2021-06-03-17:41:55.080 [nioEventLoopGroup-2-1] WARN io.netty.channel.nio.NioEventLoop - Selector.select() returned prematurely 512 times in a row; rebuilding Selector org.apache.plc4x.java.transport.serial.SerialPollingSelector#48c328c5.
With same URL data (i.e baudrate,stopBits etc..) using modpoll.exe it works and returns the data over RTU. I am not sure what is missing here.
Kindly shed some light here.

Efficient way to optimise a Scala code to read large file that doesn't fit in memory

Problem Statement Below,
We have a large log file which stores user interactions with an application. The entries in the log file follow the following schema: {userId, timestamp, actionType} where actionType is one of two possible values: [open, close]
Constraints:
The log file is too big to fit in memory on one machine. Also assume that the aggregated data doesn’t fit into memory.
Code has to be able to run on a single machine.
Should not use an out-of-the box implementation of mapreduce or 3rd party database; don’t assume we have a Hadoop or Spark or other distributed computing framework.
There can be multiple entries of each actionType for each user, and there might be missing entries in the log file. So a user might be missing a close record between two open records or vice versa.
Timestamps will come in strictly ascending order.
For this problem, we need to implement a class/classes that computes the average time spent by each user between open and close. Keep in mind that there are missing entries for some users, so we will have to make a choice about how to handle these entries when making our calculations. Code should follow a consistent policy with regards to how we make that choice.
The desired output for the solution should be [{userId, timeSpent},….] for all the users in the log file.
Sample log file (comma-separated, text file)
1,1435456566,open
2,1435457643,open
3,1435458912,open
1,1435459567,close
4,1435460345,open
1,1435461234,open
2,1435462567,close
1,1435463456,open
3,1435464398,close
4,1435465122,close
1,1435466775,close
Approach
Below is the code I've written in Python & Scala, which seems to be not efficient and upto the expectations of the scenario given, I'd like to feedback from community of developers in this forum how better we could optimise this code as per given scenario.
Scala implementation
import java.io.FileInputStream
import java.util.{Scanner, Map, LinkedList}
import java.lang.Long
import scala.collection.mutable
object UserMetrics extends App {
if (args.length == 0) {
println("Please provide input data file name for processing")
}
val userMetrics = new UserMetrics()
userMetrics.readInputFile(args(0),if (args.length == 1) 600000 else args(1).toInt)
}
case class UserInfo(userId: Integer, prevTimeStamp: Long, prevStatus: String, timeSpent: Long, occurence: Integer)
class UserMetrics {
val usermap = mutable.Map[Integer, LinkedList[UserInfo]]()
def readInputFile(stArr:String, timeOut: Int) {
var inputStream: FileInputStream = null
var sc: Scanner = null
try {
inputStream = new FileInputStream(stArr);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
val line: String = sc.nextLine();
processInput(line, timeOut)
}
for ((key: Integer, userLs: LinkedList[UserInfo]) <- usermap) {
val userInfo:UserInfo = userLs.get(0)
val timespent = if (userInfo.occurence>0) userInfo.timeSpent/userInfo.occurence else 0
println("{" + key +","+timespent + "}")
}
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
}
def processInput(line: String, timeOut: Int) {
val strSp = line.split(",")
val userId: Integer = Integer.parseInt(strSp(0))
val curTimeStamp = Long.parseLong(strSp(1))
val status = strSp(2)
val uInfo: UserInfo = UserInfo(userId, curTimeStamp, status, 0, 0)
val emptyUserInfo: LinkedList[UserInfo] = new LinkedList[UserInfo]()
val lsUserInfo: LinkedList[UserInfo] = usermap.getOrElse(userId, emptyUserInfo)
if (lsUserInfo != null && lsUserInfo.size() > 0) {
val lastUserInfo: UserInfo = lsUserInfo.get(lsUserInfo.size() - 1)
val prevTimeStamp: Long = lastUserInfo.prevTimeStamp
val prevStatus: String = lastUserInfo.prevStatus
if (prevStatus.equals("open")) {
if (status.equals(lastUserInfo.prevStatus)) {
val timeSelector = if ((curTimeStamp - prevTimeStamp) > timeOut) timeOut else curTimeStamp - prevTimeStamp
val timeDiff = lastUserInfo.timeSpent + timeSelector
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, timeDiff, lastUserInfo.occurence + 1))
} else if(!status.equals(lastUserInfo.prevStatus)){
val timeDiff = lastUserInfo.timeSpent + curTimeStamp - prevTimeStamp
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, timeDiff, lastUserInfo.occurence + 1))
}
} else if(prevStatus.equals("close")) {
if (status.equals(lastUserInfo.prevStatus)) {
lsUserInfo.remove()
val timeSelector = if ((curTimeStamp - prevTimeStamp) > timeOut) timeOut else curTimeStamp - prevTimeStamp
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, lastUserInfo.timeSpent + timeSelector, lastUserInfo.occurence+1))
}else if(!status.equals(lastUserInfo.prevStatus))
{
lsUserInfo.remove()
lsUserInfo.add(UserInfo(userId, curTimeStamp, status, lastUserInfo.timeSpent, lastUserInfo.occurence))
}
}
}else if(lsUserInfo.size()==0){
lsUserInfo.add(uInfo)
}
usermap.put(userId, lsUserInfo)
}
}
Python Implementation
import sys
def fileBlockStream(fp, number_of_blocks, block):
#A generator that splits a file into blocks and iterates over the lines of one of the blocks.
assert 0 <= block and block < number_of_blocks #Assertions to validate number of blocks given
assert 0 < number_of_blocks
fp.seek(0,2) #seek to end of file to compute block size
file_size = fp.tell()
ini = file_size * block / number_of_blocks #compute start & end point of file block
end = file_size * (1 + block) / number_of_blocks
if ini <= 0:
fp.seek(0)
else:
fp.seek(ini-1)
fp.readline()
while fp.tell() < end:
yield fp.readline() #iterate over lines of the particular chunk or block
def computeResultDS(chunk,avgTimeSpentDict,defaultTimeOut):
countPos,totTmPos,openTmPos,closeTmPos,nextEventPos = 0,1,2,3,4
for rows in chunk.splitlines():
if len(rows.split(",")) != 3:
continue
userKeyID = rows.split(",")[0]
try:
curTimeStamp = int(rows.split(",")[1])
except ValueError:
print("Invalid Timestamp for ID:" + str(userKeyID))
continue
curEvent = rows.split(",")[2]
if userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==1 and curEvent == "close":
#Check if already existing userID with expected Close event 0 - Open; 1 - Close
#Array value within dictionary stores [No. of pair events, total time spent (Close tm-Open tm), Last Open Tm, Last Close Tm, Next expected Event]
curTotalTime = curTimeStamp - avgTimeSpentDict[userKeyID][openTmPos]
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
avgTimeSpentDict[userKeyID][totTmPos] = totalTime
avgTimeSpentDict[userKeyID][closeTmPos] = curTimeStamp
avgTimeSpentDict[userKeyID][nextEventPos] = 0 #Change next expected event to Open
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==0 and curEvent == "open":
avgTimeSpentDict[userKeyID][openTmPos] = curTimeStamp
avgTimeSpentDict[userKeyID][nextEventPos] = 1 #Change next expected event to Close
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==1 and curEvent == "open":
curTotalTime,closeTime = missingHandler(defaultTimeOut,avgTimeSpentDict[userKeyID][openTmPos],curTimeStamp)
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
avgTimeSpentDict[userKeyID][totTmPos]=totalTime
avgTimeSpentDict[userKeyID][closeTmPos]=closeTime
avgTimeSpentDict[userKeyID][openTmPos]=curTimeStamp
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
elif userKeyID in avgTimeSpentDict.keys() and avgTimeSpentDict[userKeyID][nextEventPos]==0 and curEvent == "close":
curTotalTime,openTime = missingHandler(defaultTimeOut,avgTimeSpentDict[userKeyID][closeTmPos],curTimeStamp)
totalTime = curTotalTime + avgTimeSpentDict[userKeyID][totTmPos]
avgTimeSpentDict[userKeyID][totTmPos]=totalTime
avgTimeSpentDict[userKeyID][openTmPos]=openTime
eventCount = avgTimeSpentDict[userKeyID][countPos] + 1
avgTimeSpentDict[userKeyID][countPos] = eventCount
elif curEvent == "open":
#Initialize userid with Open event
avgTimeSpentDict[userKeyID] = [0,0,curTimeStamp,0,1]
elif curEvent == "close":
#Initialize userid with missing handler function since there is no Open event for this User
totaltime,OpenTime = missingHandler(defaultTimeOut,0,curTimeStamp)
avgTimeSpentDict[userKeyID] = [1,totaltime,OpenTime,curTimeStamp,0]
def missingHandler(defaultTimeOut,curTimeVal,lastTimeVal):
if lastTimeVal - curTimeVal > defaultTimeOut:
return defaultTimeOut,curTimeVal
else:
return lastTimeVal - curTimeVal,curTimeVal
def computeAvg(avgTimeSpentDict,defaultTimeOut):
resDict = {}
for k,v in avgTimeSpentDict.iteritems():
if v[0] == 0:
resDict[k] = 0
else:
resDict[k] = v[1]/v[0]
return resDict
if __name__ == "__main__":
avgTimeSpentDict = {}
if len(sys.argv) < 2:
print("Please provide input data file name for processing")
sys.exit(1)
fileObj = open(sys.argv[1])
number_of_chunks = 4 if len(sys.argv) < 3 else int(sys.argv[2])
defaultTimeOut = 60000 if len(sys.argv) < 4 else int(sys.argv[3])
for chunk_number in range(number_of_chunks):
for chunk in fileBlockStream(fileObj, number_of_chunks, chunk_number):
computeResultDS(chunk, avgTimeSpentDict, defaultTimeOut)
print (computeAvg(avgTimeSpentDict,defaultTimeOut))
avgTimeSpentDict.clear() #Nullify dictionary
fileObj.close #Close the file object
Both program above gives desired output, but efficiency is what matters for this particular scenario. Let me know if you've anything better or any suggestions on existing implementation.
Thanks in Advance!!
What you are after is iterator usage. I'm not going to re-write your code, but the trick here is likely to be using an iterator. Fortunately Scala provides decent out of the box tooling for the job.
import scala.io.Source
object ReadBigFiles {
def read(fileName: String): Unit = {
val lines: Iterator[String] = Source.fromFile(fileName).getLines
// now you get iterator semantics for the file line traversal
// that means you can only go through the lines once, but you don't incur a penalty on heap usage
}
}
For your use case, you seem to require a lastUser, so you're dealing with groups of 2 entries. I think you you have two choices, either go for iterator.sliding(2), which will produce iterators for every pair, or simply add recursion to the mix using options.
def navigate(source: Iterator[String], last: Option[User]): ResultType = {
if (source.hasNext) {
val current = source.next()
last match {
case Some(existing) => // compare with previous user etc
case None => navigate(source, Some(current))
}
} else {
// exit recursion, return result
}
}
You can avoid all the code you've written to read the file and so on. If you need to count occurrences, simply build a Map inside your recursion, and increment the occurrences at every step based on your business logic.
from queue import LifoQueue, Queue
def averageTime() -> float:
logs = {}
records = Queue()
with open("log.txt") as fp:
lines = fp.readlines()
for line in lines:
if line[0] not in logs:
logs[line[0]] = LifoQueue()
logs[line[0]].put((line[1], line[2]))
else:
logs[line[0]].put((line[1], line[2]))
for k in logs:
somme = 0
count = 0
while not logs[k].empty():
l = logs[k].get()
somme = (somme + l[0]) if l[1] == "open" else (somme - l[0])
count = count + 1
records.put([k, somme, count//2])
while not records.empty():
record = records.get()
print(f"UserId={record[0]} Avg={record[1]/record[2]}")

How to make a live counter in unity3d

I recently started using Unity3D and made a few levels. The only problem I have right now is how can I get a live counter?
So my character dies when he hits and certain object.
I want my character to get 3 lives maximum, and get -1 live when he hits that object.
And that it keeps the data when he dies so you wouldn't get lives back if you restart the app.
And after a certain amount of minutes he gets +1 live.
Thank you :)
While your game running. just create a variable counterTime to count time, whenever counterTime pass certain amount of time you want reset counterTime to 0 and increase your life.
When user quit your app, save last time to PlayerPref, eg:
PlayerPref.SaveString("LastTime", DateTime.Now);
When user comback game, just check duration between last time and now to calculate total life need added. eg:
DateTime lastTime = DateTime.Parse(PlayerPref.GetString("LastTime"));
TimeSpan timeDif= DateTime.Now - lastTime;
int duration = timeDif.TotalSeconds;
You can use PlayerPrefs.SetInt , PlayerPrefs.GetInt for storing and reading your player's hp in file storage. Read more about it here:
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
As for Giving player +1 hp after a few minutes you can store DateTime.Now in a PlayerPrefs variable whenever you give your player some hp and use TimeSpan and TotalMinutesPassed:
TimeSpan passedTime = DateTime.Now - lastStoredDateTime;
int totalMinutesPassed = passedTime.TotalMinutes;
Should go sth like this i guess(didnt test this code just showing a general idea) :
void SetPlayerLives(int lives)
{
playerLives = lives;
PlayerPrefs.SetInt("player-lives",playerLives);
}
//TODO: also sth like => int GetPlayerLives() function
void CheckLiveRegen() //call this function whenever you want to check live regen:
{
int LIVE_REGEN_MINUTES = 5; //regen 1 live every 5 minutes
DateTime lastStoredDateTime = DateTime.Parse(PlayerPrefs.GetString("last-live-regen", DateTime.Now.ToString()));
TimeSpan passedTime = DateTime.Now - lastStoredDateTime;
double totalMinutesPassed = passedTime.TotalMinutes;
if(totalMinutesPassed >= LIVE_REGEN_MINUTES)
{
int val = (int) totalMinutesPassed / LIVE_REGEN_MINUTES;
// Add val to your player lives! + store new lives value
SetPlayerLives(playerLives+val);
//update last-live-regen value:
PlayerPrefs.SetString("last-live-regen", DateTime.Now.ToString());
}
}
Note: DateTime , TimeSpan classes have some bugs (specially in android platform) in versions older than 2017.4 (LTS) Make sure you log values and check if functions are working properly.
https://forum.unity.com/threads/android-datetime-now-is-wrong.488380/
check out the following link to understand how to create a life counter in unity
http://codesaying.com/life-counter-in-unity/
In order to calculate the time that was lapsed since you last shut down the game, you should save the last time playerprefs in the function OnApplicationPause and calcuate the timelapsed in the Awake Function.
void Awake () {
if(!PlayerPrefs.HasKey("Lives")){
PlayerPrefs.SetString("LifeUpdateTime", DateTime.Now.ToString());
}
lives = PlayerPrefs.GetInt("Lives", maxLives);
//update life counter only if lives are less than maxLives
if (lives < maxLives)
{
float timerToAdd = (float)(System.DateTime.Now - Convert.ToDateTime(PlayerPrefs.GetString("LifeUpdateTime"))).TotalSeconds;
UpdateLives(timerToAdd);
}
}
void UpdateLives(double timerToAdd ){
if (lives < maxLives)
{
int livesToAdd = Mathf.FloorToInt((float)timerToAdd / lifeReplenishTime);
timerForLife = (float)timerToAdd % lifeReplenishTime;
lives += livesToAdd;
if (lives > maxLives)
{
lives = maxLives;
timerForLife = 0;
}
PlayerPrefs.SetString("LifeUpdateTime", DateTime.Now.AddSeconds(-timerForLife).ToString());
}else{
PlayerPrefs.SetString("LifeUpdateTime", DateTime.Now.ToString());
}
}
void OnApplicationPause(bool isPause)
{
if (isPause)
{
timeOfPause = System.DateTime.Now;
}
else
{
if(timeOfPause == default(DateTime)){
timeOfPause = System.DateTime.Now;
}
float timerToAdd = (float)(System.DateTime.Now - timeOfPause).TotalSeconds;
timerForLife += timerToAdd;
UpdateLives(timerForLife);
}
}
}

How to use simulation time to triger action in modules?

I want to create simulation with server and 2 nodes. Nodes have defined vector that contain times for turn on/off.(example timersOnOff = 5,10,13,25 … nod will turn on in 5th second of beginning simulation, and then will be shutdown in 10th seconds etc). How to trigger action at certain time to send msg to node to "turn on" or "turn off".?
Let's assume that these times are written in timersOnOff declared as:
std::vector<simtime_t> timersOnOff;
In initialize() add the following code:
for (int i = 0; i < timersOnOff.size(); i = i + 2) {
simtime_t timeOn = timersOnOff[i];
simtime_t timeOff = timersOnOff[i+1];
cMessage * msgOn = new cMessage("nodeOn"); // (1)
cMessage * msgOff = new cMessage("nodeOff"); // (2)
scheduleAt (timeOn, msgOn);
scheduleAt (timeOff, msgOff);
}
The above code schedules all ON and OFF events.
Then, in handleMessage() add:
if (msg->isSelfMessage()) {
if (msg->isName("nodeOn")) { // the same name as in (1)
delete msg;
// turning on the node
} else if (msg->isName("nodeOff")) { // the same name as in (2)
delete msg;
// turning off the node
}
} else {
// ...
}

merge performance in Functional Reactive programming (RX)

In the following code:
http://jsfiddle.net/staltz/4gGgs/27/
var clickStream = Rx.Observable.fromEvent(button, 'click');
var multiClickStream = clickStream
.buffer(function() { return clickStream.throttle(250); })
.map(function(list) { return list.length; })
.filter(function(x) { return x > 1; });
// Same as above, but detects single clicks
var singleClickStream = clickStream
.buffer(function() { return clickStream.throttle(250); })
.map(function(list) { return list.length; })
.filter(function(x) { return x === 1; });
// Listen to both streams and render the text label accordingly
singleClickStream.subscribe(function (event) {
document.querySelector('h2').textContent = 'click';
});
multiClickStream.subscribe(function (numclicks) {
document.querySelector('h2').textContent = ''+numclicks+'x click';
});
Rx.Observable.merge(singleClickStream, multiClickStream)
.throttle(1000)
.subscribe(function (suggestion) {
document.querySelector('h2').textContent = '';
});
How many times clickStream sequence will be iterated after merge?
I mean, will it look like this:
case 1
for(numclicks : clickStream.length){
if (numclicks === 1){
document.querySelector('h2').textContent = 'click';
}
};
for(numclicks : clickStream.length){
if (numclicks > 1){
document.querySelector('h2').textContent = ''+numclicks+'x click';
}
};
Or it will be internally, really merged to something like this (pseudocode):
case 2
for(numclicks: clickStream.length){
if (numclicks === 1){
document.querySelector('h2').textContent = 'click';
}else if(numclicks > 1){
document.querySelector('h2').textContent = ''+numclicks+'x click';
}
}
I personally think, that merge just sequentially apply stream to its arguments (case 1).
P.S. I hope there is some standart for things like this. But if no - I particularly interested in RxCpp and Sodium implementation.
I took js example, as more interactive.
fromEvent returns a hot source and so all subscribers share the same iteration of the for loop.
Ignoring the throttle calls, the result is similar to:
for(numclicks: clickStream.length){
// first subscription
if (numclicks === 1){
document.querySelector('h2').textContent = 'click';
}
// second subscription
if(numclicks > 1){
document.querySelector('h2').textContent = ''+numclicks+'x click';
}
// merged subscription
if (numclicks === 0) {
document.querySelector('h2').textContent = '';
}
}
The throttle calls mean that the body of the sole click stream for loop is actually just pushing click events into two buffers and reseting the timer in each of the three throttle operators. h2 is set when one of the three throttle timers fires. since the timers are not shared it is like a separate for loop per throttle timer with each loop setting h2 to only one of the three possible values:
This behavior is similar in all the Rx family.
Regarding rxcpp in particular:
rxcpp is missing the buffer overload that allows a observable to trigger a transition to a new buffer.
rxcpp does not have throttle implemented yet.
rxcpp is not thread-safe by default (pay-for-play) so if the throttle timers used introduce threads, then coordinations must be used to explicitly add thread-safety.