I'm using the Prometheus Java simpleclient within a web service to keep track of how many events result in one status or another.
I'm able to check within the logs that the counter is being invoked and is incrementing internally, but it seems that a lot of times the data is not making it to the /metrics endpoint.
For example, just now, after incrementing the counter 3 times for the same status a few minutes apart each, the log would print out "Current Value = 0, New value = 1" three times. The first two times did not show any data on the /metrics endpoint, and after the 3rd increment, it finally showed a value of 1, which means I lost the record of the first 2 events.
The code I have is the following below, besides some name changes.
private static final Counter myCounter = Counter.build()
.name("myMetric")
.help("My metric")
.labelNames("status").register();
...
private static void incrementCounter(String status) {
Counter.Child counter = myCounter.labels(status);
Logger.info("Before Incrementing counter for status= " + status + ". Current value=" + counter.get());
counter.inc();
Logger.info("After Incrementing counter for status= " + status + ". New value=" + counter.get());
}
I'm at a loss as for why Prometheus doesn't seem to be able to keep track of these counters consistently. Is anyone able to see what's wrong or a better way to record these Counter metrics?
The only reason I can guess are concurrent incrementCounter calls.
The io.prometheus.client.SimpleCollector#labels method is not thread-safe (despite that children field has ConcurrentMap type), thus it is possible to get different io.prometheus.client.Counter.Child on every call.
As for getting metrics via http - every call to /metrics endpoint leads to io.prometheus.client.Counter#collect method call, which retrieves value of the only one child.
I would suggest you to use your own concurrent map to store counters:
private static final ConcurrentMap<String, Counter.Child> counters = new ConcurrentHashMap<>();
// ...
private static void incrementCounter(String status) {
Counter.Child counter = counters.computeIfAbsent(status, myCounter::labels) ;
// ...
}
Related
I'm trying to get the user's speed 10 times in three seconds when a function is called, and then calculate the sum of all the gotten values. I have the global variable:
lateinit var fusedLocationProviderClient : FusedLocationProviderClient
Which I then initialize in the onCreate method like this:
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
And then this is the code where I try to calculate the sum of the speeds:
val task = fusedLocationProviderClient.lastLocation
var sumSpeed = 0F
task.addOnSuccessListener {
if (it != null) {
for (i in 1..10) {
Thread.sleep(300)
sumSpeed += it.speed
}
}
current_gps_speed_tv.text = "Total is: $sumSpeed"
if (sumSpeed < 25) {
...
}
}
The result of sumSpeed always remains the same (34m/s), which is 10 times it.speed, which is also the same every time (3.4m/s).
I've searched for other answers (like this one) but what I'm using seems to be different. Why does this happen? Thank you.
This won't work for at least a few different reasons.
You're trying to poll it more than once per second. I think the fastest rate position is updated is at best once per second, and it's going to depend on device.
You are simply adding the same value to the sum 10 times and sleeping the thread pointlessly. Calling sleep pauses execution of your code. It does not magically change the value of it to some new value polled from the GPS.
Calling Thread.sleep on the main thread will freeze your app.
You are polling lastLocation, which is some location already known from the last time the GPS was used. It only reports a single value that comes from the past. It cannot report multiple new values. Your success listener is called only one time, because either the last location is available or it's not.
To get multiple locations over a period of time, you need to use requestLocationUpdates instead of lastLocation. See here for the documentation.
Edit, to expand on 2 based on your comment:
Imagine this code:
val x = 5
var sum = 0
for (i in 0..9) {
sum = sum + 5
}
println(sum)
This adds the value of x to sum 10 times, so the result will be 50.
Now consider this code:
val x = 5
var sum = 0
for (i in 0..9) {
Thread.sleep(100)
sum = sum + 5
}
println(sum)
This code has the exact same result. It just takes a lot longer to return because it keeps pausing to sleep. Sleeping has no effect on the value of x. x is always the same value. The same is true of it in your code. There is only ever one instance of it in your function.
So I have two question.
Let's start with the first one, how do you make two readCharacteristic after eachothers? the code I've showed is what I was thinking you could do it. But because onCharacteristicRead isn't called yet in the first readCharacteristic call the next readCharacteristic isn't triggered. Here i solved it by calling the second readCharacteristic in the if-statement for the first readCharacteristic in the onCharacteristicRead, but i don't know it this is normal/stupid solution?
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
BluetoothGattService mBluetoothGattService = gatt.getService(UUID.fromString(CSUuid));
if (mBluetoothGattService != null) {
Log.i(TAG, "Connection State: Service characteristic UUID found: " + mBluetoothGattService.getUuid().toString());
mCharacterisitc = mBluetoothGattService.getCharacteristic(UUID.fromString(UuidRead));
mCharacterisitc2 = mBluetoothGattService.getCharacteristic(UUID.fromString(UuidRead2));
Log.w(TAG, "Connection State 1: mCharacterisitc " + mCharacterisitc + " " + mCharacterisitc2);
readCharacteristic(gatt, mCharacterisitc);
//I know I have to wait for the above is done, but can I do it here instead of
//calling the line under in onCharacteristicRead?
readCharacteristic(gatt, mCharacterisitc2);
} else {
Log.i(TAG, "Connection State: Service characteristic not found for UUID: " + UuidRead);
}
}
}
Next question is a bit hard I think?
the code is made in PSoC creator 4.3
So at the moment I read a single int from my PSoC 6 BLE device, and another letter 'M' converted to a integer and back to a 'M' on the app-side. The reason I only read a SIGNLE 'M' is because I don't know how to send a whole string like 'Made it'. I think the issue I'm having is on the PSoC side where I don't know how to read a whole string.
for(;;)
{
/* Place your application code here. https://www.youtube.com/watch?v=Aeip0hkc4YE*/
cy_stc_ble_gatt_handle_value_pair_t serviceHandle;
cy_stc_ble_gatt_value_t serviceData;
//this is the variables I've declared earlier in the code
//static uint8 data[1] = {0};
//static char * ValStr;
//here I just have a simple Integer which count up every sec
serviceData.val = (uint8*)data;
serviceData.len = 1;
serviceHandle.attrHandle = CY_BLE_CUSTOM_SERVICE_DEVICE_OUTBOUND_CHAR_HANDLE;
serviceHandle.value = serviceData;
Cy_BLE_GATTS_WriteAttributeValueLocal(&serviceHandle); //sending the data to -> OUTBOUND
//this part should probably not be in a for-loop, but for now it is.
ValStr = "Mads Sander Hoegstrup"; //I want read whole string on my android APP
serviceData.val = (uint8*) ValStr; //this only takes the 'M' and thats the only variable I can read from my APP not the rest of the string
serviceData.len = 1; //Does not help to increase, if it's more than 1 I read 0 and not a letter
serviceHandle.attrHandle = CY_BLE_CUSTOM_SERVICE_DEVICE_OUTBOUND_2_CHAR_HANDLE;
serviceHandle.value = serviceData;
Cy_BLE_GATTS_WriteAttributeValueLocal(&serviceHandle); //sending the data to -> OUTBOUND_2
data[0]++;
CyDelay(1000);
}
Here you can see that I revice the right values, a Integer and a String, but only the letter 'M' and not the string 'Mads Sander Hoegstrup'
Just ask if you want more information
You'd better ask two separate questions, since they have nothing to do with each other.
I'll answer the first question. You cannot wait inside the onServicesDiscovered method between the two reads. Even if you wait for 30 seconds it will not work. The reason is that only one thread can run a callback on each BluetoothGatt object at the same time, and it's the caller of onCharacteristicRead that clears the internal gatt busy flag which otherwise prevents you from submitting another request. You'd better implement some queue mechanism to keep the code cleaner if you like.
I need to write two programs. 1 sequential (Done) and 1 parallel and I've done something but i don't know if I've made it parallel or not and i also need to know:
If (Thread.State state = Thread.currentThread().getState();) is the code to display the status of a thread
how to assign different threads to different processors (4 cores)
How to display the status of the processor
calculation for each processor
how to generate error messeges(Memory Consistency Errors, etc.)
Following is my code:
class Threads implements Runnable {
#Override
public void run() {
Thread t = Thread.currentThread();
Thread.State state = Thread.currentThread().getState();
String Assignment = "calculations in array";
String name = "os.name";
String version = "os.version";
String architecture = "os.arch";
String[] array = new String[1312500];
int size = array.length;
Random r = new Random();
int[] values = new int[1312500];
int sumarray = 0;
int CountD = 0;
for (int i = 0; i < values.length; i++) {
int randomint = r.nextInt(100);
values[i] = randomint;
if ((values[i] % 2 != 0) && (values[i] >= 25 && values[i] <= 75)) {
sumarray += values[i];
CountD++;
}
}
System.out.println(t.getName());
System.out.println("Thread Id " + t.getId());
System.out.println("Thread Priority " + t.getPriority());
System.out.println("status " + state);
System.out.println("OS Name: " + System.getProperty(name));
System.out.println("OS Version: " + System.getProperty(version));
System.out.println("OS Architechture: " + System.getProperty(architecture));
System.out.println(Assignment);
System.out.println("Size of the Array is: " + array.length);
System.out.println("Total number of system cores(processors): " + Runtime.getRuntime().availableProcessors());
System.out.println("Difference of Array and Processors 1312500/4 = "
+ array.length / Runtime.getRuntime().availableProcessors());
System.out.println("The size of array is divisible by the number of processors");
System.out.println("Summary is: " + sumarray);
System.out.println("The Average is: " + (sumarray / CountD));
}
}
Main class:
class Concurrent {
public static void main(String[] args) {
Thread t1 = new Thread(new Threads());
t1.start();
Thread t2 = new Thread(new Threads());
t2.start();
Thread t3 = new Thread(new Threads());
t3.start();
Thread t4 = new Thread(new Threads());
t4.start();
}
}
[I need to know] If Thread.State state = Thread.currentThread().getState(); is the code to display the status of a thread.
That declares a variable named state and initializes it with the state of the thread in which it is executed. (https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html
That code snippet doesn't display anything, but the subsequent System.out.println("status " + state); will write a representation of the state out to the console.
I have no way of knowing know whether Thread.State corresponds to what you call "status", but calling Thread.currentThread().getState(); yields no information because the state of any thread will always be RUNNABLE while it is calling getState().
[I need to know] how to assign different threads to different processors
I bet you don't.
What you are asking about is called "processor affinity." Most programs rely on the operating system to automatically schedule runnable threads on available CPUs. It's only very sophisticated programs (and note, "sophisticated" does not always equal "good") that need to tinker with it.
There is no standard way to set the CPU affinity of Java threads, but there might be some means that you can use on your particular operating system. You can google "Java processor affinity" for more info.
[I need to know] How to display the status of the processor
You're going to have to explain what "status" means and also, which processor, and when?
Depending on what "status" means, If you write code to ask for the "status" of the same processor that the code is running on, then the answer probably will never change. Just like how the result of Thread.currentThread().getState() never changes.
Processor "status" is the sort of thing that sysadmins of big data centers like to see plotted on charts, but they seldom are useful within a program unless, once again, you are doing something very sophisticated.
[I need to know] how to generate error messeges.
The simplest way to do that is to use System.out.println(...) or System.err.println(...)
Maybe you really meant to ask something else, like how to know when to report an error, or how to handle exceptions.
Most Java library routines throw an exception when something goes wrong. All you have to do in that case is completely ignore it. If you don't write any code to handle the exception, then your program will automatically print an error message and stop when the exception is thrown.
how to assign different threads to different processors (4 cores)
Let's leave this decision to java runtime. From programmer perspective, try to use the features available to you.
For effective utilizaiton of CPU cores, have a look at this question:
Java: How to scale threads according to cpu cores?
Regarding processor affinity, you can check posts:
Java thread affinity
http://tools.assembla.com/Behemoth/browser/Tests/JAVA/test/src/main/java/test/threads/ThreadAffinity.java ( written by BegemoT)
But you should avoid these type of things and focus on business logic.
how to generate error messeges(Memory Consistency Errors, etc.)
You can easily generate memory consistency errors.
Do not protect your code with thread safe constructs like synchronized or Lock and allow multiple threads to update data from your class.
Have a look at this documentation page
Refer to documentation links for better understanding of multi-threading concepts.
I am developing desktop app in Java 7. I have here a situation. At the method below
private synchronized void decryptMessage
(CopyOnWriteArrayList<Integer> possibleKeys, ArrayList<Integer> cipherDigits)
{
// apply opposite shift algorithm:
ArrayList<Integer> textDigits = shiftCipher(possibleKeys, cipherDigits);
// count CHI squared statistics:
double chi = countCHIstatistics(textDigits);
if(chi < edgeCHI) // if the value of IOC is greater or equal than that
{
System.err.println(chi + " " + possibleKeys + " +");
key = possibleKeys; // store most suitable key
edgeCHI = chi;
}
}
I count the value called 'chi' and based on that if 'chi' is less than 'edgeCHI' value I save the key at instance variable. That method is invoked by some threads, so I enforce synchronization.
When all the threads complete the program continues to execute by passing control to a method which controls the sequence of operations. Then this line has been executed at that method:
System.err.println(edgeCHI+" "+key+" -");
It prints correct value of 'chi', as has been printed the last value of 'chi' at decryptMessage method, but the value of key is different. The 'decryptMessage' method has been invoked by threads which generate key values.
I store the key value as global variable
private volatile CopyOnWriteArrayList<Integer> key = null; // stores the most suitable key for decryption.
Why do I have two different key values? The values itself are not important. The matter is that the value of key printed at the last call at 'decryptMessage' method (when chi < edgeCHI) must match the one printed at the method which controls the flow of operations.
This is how you create threads:
for(int y = 0; y < mostOccuringL.length; y++){// iterate through the five most frequent letters
for(int i = (y + 1); i < mostOccuringL.length; i++ ){//perform letter combinations
int [] combinations = new int[2];
combinations[0] = y;
combinations [1] = i;
new KeyMembers(""+y+":"+i ,combinations, keywords, intKeyIndex, cipherDigits).t.join();
}
}
Within run method you invoke decryptMesssage method in order to identify most feasible decryption key.
I have been trying to figure out what is the prob for two days, but I don't get it.
Suggestions?
Relying on syserr (or sysout) printing to determine an order of execution is dangerous - especially in multi-threaded environments. There is absolutely no guarantuee when the printing actually occurs or if the printed messages are in order. Maybe what you see as "last" printed message of one of the threads wasn't the "last" thread modifying the key field. You cannot say that by looking only at sterr output.
What you could do is use a synchronized setter for the key field, that increases an associated access counter whenever the field is modified and print the new value along with the modification count. This way you can avoid the problems of syserr printing and reliably determine what the last set value was. e.g. :
private long keyModCount = 0;
private synchronized long update(CopyOnWriteArrayList<Integer> possibilities, double dgeChi) {
this.keys = possibilites;
this.edgeChi = edgeChi; // how is edgeChi declared? Also volatile?
this.keyModCount++;
return this.keyModCount;
}
And inside decryptMessage:
if(chi < edgeCHI) // if the value of IOC is greater or equal than that
{
long sequence = update(possibleKeys, chi);
System.err.println("["+ sequence +"]"+ chi + " " + possibleKeys + " +");
}
To provide an answer we would need to see more of the (simplified if necessary) code that controls the thread execution.
Solution has been found. I just changed CopyOnWriteArrayList data type into ArrayList at the point where field variable gets correct key. It works as expected now.
I'm trying to build out a simple app engine datastore entity that basically keeps count of how many times it was viewed. I've got the code setup in a JSP file that does increment the variable, however every time it seems to increment by 2 rather than one. Here's the code in question.
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity story = datastore.get(KeyFactory.stringToKey(request.getParameter("story_key")));
String json_out = "";
int num_views = 0;
if(story.getProperty("views") != null) {
num_views = Integer.parseInt(story.getProperty("views").toString());
}
//Update the donated status of this object.
story.setProperty("views", num_views + 1);
datastore.put(story);
json_out += "{";
json_out += "\"title\":\"" + story.getProperty("title") + "\", ";
json_out += "\"views\":\"" + num_views + "\"";
json_out += "}";
out.println(json_out);
Any idea why it would be incrementing by 2? I've even tried subtracting one when I get the number of views, but then the number just stays the same all the time as you'd expect. Really odd.
If you are implementing a counter using the datastore, you should you techniques that allow for high throughput. Your solution above could easily write to the datastore more than a few times per second, violating HRD policies. Also, it's not thread safe (not run in a transaction, so updates could apply out of order and your result is not what you expect). Try out shard counters, which fix these issues:
http://code.google.com/appengine/articles/sharding_counters.html