Regarding #18
Concerns mostly:
@Emily-Jiang @cealsair @rdebusscher
Hi guys, so this is what I suggest as a solution. if it doesn't stir up any opposition I will go ahead and forge this little demo into an application scoped bean callable from GeneratorDataBean.java. Rudy might suggest a better integration though...
AmazonDynamoDB
We host the service on Amazon, so there is probably no harm in using it for a simple logging of loosely structured data rows. If we want to leave, we always can. Moving away is as easy as dumping that log into JSON and importing it into something else.
Demo of what we might log
(This is just a showcase, not integrated, it is hard coded, demo, etc.)
package org.eclipse.microprofile.starter;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.PutItemOutcome;
import com.amazonaws.services.dynamodbv2.document.Table;
import org.junit.Test;
import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Michal Karm Babacek <[email protected]>
*/
public class DownloadsLoggerDemoTest {
@Test
public void demoLoggingTest() throws NoSuchAlgorithmException {
final AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
//.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "eu-west-1"))
.withRegion(Regions.EU_WEST_1)
.build();
final DynamoDB dynamoDB = new DynamoDB(client);
try {
final Table table = dynamoDB.getTable("microprofile_starter_log");
final Calendar calendar = Calendar.getInstance();
final SimpleDateFormat formattedTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
final MessageDigest hash = MessageDigest.getInstance("SHA-1");
// Logged
final String mpVersion = "2.0";
final String supportedServer = "liberty";
final String beansxmlMode = "ANNOTATED";
final String moduleStructure = "SINGLE";
final Set<String> selectedSpecs = Stream.of("HEALTH_METRICS", "HEALTH_CHECKS", "REST_CLIENT").collect(Collectors.toSet());
final String timestamp = formattedTime.format(calendar.getTime());
// Just used to add entropy to unique stamp
final String groupId = "biz.kamrs";
final String artifacId = "demodemo";
// This should uniquely mark log record row. World wouldn't end if there is a collision though
final String logmark = Stream.concat(
Stream.of(mpVersion, supportedServer, beansxmlMode, moduleStructure, timestamp, groupId, artifacId),
selectedSpecs.stream()
).collect(Collectors.joining());
hash.update(logmark.getBytes());
final String hashedLogmark = DatatypeConverter.printHexBinary(hash.digest());
System.out.println("logmark:" + logmark);
System.out.println("logmark hashed:" + hashedLogmark);
final Item item = new Item()
.withPrimaryKey("logmark", hashedLogmark)
.withString("mpVersion", mpVersion)
.withString("supportedServer", supportedServer)
.withString("beansxmlMode", beansxmlMode)
.withString("moduleStructure", moduleStructure)
.withStringSet("selectedSpecs", selectedSpecs)
.withString("timestamp", timestamp);
PutItemOutcome outcome = table.putItem(item);
System.out.println("Outcome:" + outcome.toString());
} finally {
client.shutdown();
}
}
}
Runtime
Once I have AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID env vars set I can run it. For testing it is possible to use local DynamoDB, but I configured the AWS DynamoDB for our account and tried it on "production" right away:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.eclipse.microprofile.starter.DownloadsLoggerDemoTest
logmark:2.0libertyANNOTATEDSINGLE2019-01-17T00:37:44.115+0100biz.kamrsdemodemoHEALTH_CHECKSREST_CLIENTHEALTH_METRICS
logmark hashed:6FB59BD3338342E6A34CA39CBDBC73012E021BB7
Outcome:{}
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.38 sec
AWS Console
I executed the "test" twice and what I can see are two log entries:
![dynamo_screenshot](https://user-images.githubusercontent.com/691097/51286407-24ffc500-19f3-11e9-9880-c94493e13f19.png)
Command line
if you have AWS command line tool installed, you can easily use DynamoDB from your shell, either complex queries or scans, this dumps everything:
$ aws dynamodb scan --table-name microprofile_starter_log
{
"Count": 2,
"Items": [
{
"moduleStructure": {
"S": "SINGLE"
},
"logmark": {
"S": "4CBCD59B08945E9C0C84DCE262DE13E700DF34D5"
},
"selectedSpecs": {
"SS": [
"HEALTH_CHECKS",
"HEALTH_METRICS",
"REST_CLIENT"
]
},
"timestamp": {
"S": "2019-01-17T00:57:04.348+0100"
},
"beansxmlMode": {
"S": "ANNOTATED"
},
"supportedServer": {
"S": "liberty"
},
"mpVersion": {
"S": "2.0"
}
},
{
"moduleStructure": {
"S": "SINGLE"
},
"logmark": {
"S": "6FB59BD3338342E6A34CA39CBDBC73012E021BB7"
},
"selectedSpecs": {
"SS": [
"HEALTH_CHECKS",
"HEALTH_METRICS",
"REST_CLIENT"
]
},
"timestamp": {
"S": "2019-01-17T00:37:44.115+0100"
},
"beansxmlMode": {
"S": "ANNOTATED"
},
"supportedServer": {
"S": "liberty"
},
"mpVersion": {
"S": "2.0"
}
}
],
"ConsumedCapacity": null,
"ScannedCount": 2
}
Question
Good / no good? IMHO it is just what we need for simple logging.