Add card dealt metrics.
This commit is contained in:
parent
89a4ceeeef
commit
adab3b7001
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2012-2017, Andy Janata
|
* Copyright (c) 2012-2018, Andy Janata
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
@ -41,6 +41,13 @@ import java.util.concurrent.TimeUnit;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
import net.socialgamer.cah.CahModule.UniqueId;
|
import net.socialgamer.cah.CahModule.UniqueId;
|
||||||
import net.socialgamer.cah.Constants.BlackCardData;
|
import net.socialgamer.cah.Constants.BlackCardData;
|
||||||
import net.socialgamer.cah.Constants.ErrorCode;
|
import net.socialgamer.cah.Constants.ErrorCode;
|
||||||
|
@ -59,13 +66,6 @@ import net.socialgamer.cah.data.QueuedMessage.MessageType;
|
||||||
import net.socialgamer.cah.metrics.Metrics;
|
import net.socialgamer.cah.metrics.Metrics;
|
||||||
import net.socialgamer.cah.task.SafeTimerTask;
|
import net.socialgamer.cah.task.SafeTimerTask;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.hibernate.Session;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Game data and logic class. Games are simple finite state machines, with 3 states that wait for
|
* Game data and logic class. Games are simple finite state machines, with 3 states that wait for
|
||||||
|
@ -178,6 +178,11 @@ public class Game {
|
||||||
private final Provider<CardcastService> cardcastServiceProvider;
|
private final Provider<CardcastService> cardcastServiceProvider;
|
||||||
private final Provider<String> uniqueIdProvider;
|
private final Provider<String> uniqueIdProvider;
|
||||||
private String currentUniqueId;
|
private String currentUniqueId;
|
||||||
|
/**
|
||||||
|
* Sequence number of cards dealt. This allows re-shuffles and re-deals to still be tracked as
|
||||||
|
* unique card deals.
|
||||||
|
*/
|
||||||
|
private long dealSeq = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new game.
|
* Create a new game.
|
||||||
|
@ -799,6 +804,7 @@ public class Game {
|
||||||
final WhiteCard card = getNextWhiteCard();
|
final WhiteCard card = getNextWhiteCard();
|
||||||
hand.add(card);
|
hand.add(card);
|
||||||
newCards.add(card);
|
newCards.add(card);
|
||||||
|
metrics.cardDealt(currentUniqueId, player.getUser().getSessionId(), card, dealSeq++);
|
||||||
}
|
}
|
||||||
sendCardsToPlayer(player, newCards);
|
sendCardsToPlayer(player, newCards);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2017, Andy Janata
|
* Copyright (c) 2017-2018, Andy Janata
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
@ -36,13 +36,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import net.socialgamer.cah.data.BlackCard;
|
|
||||||
import net.socialgamer.cah.data.CardSet;
|
|
||||||
import net.socialgamer.cah.data.WhiteCard;
|
|
||||||
import net.socialgamer.cah.db.PyxBlackCard;
|
|
||||||
import net.socialgamer.cah.db.PyxCardSet;
|
|
||||||
import net.socialgamer.cah.db.PyxWhiteCard;
|
|
||||||
|
|
||||||
import org.apache.kafka.clients.CommonClientConfigs;
|
import org.apache.kafka.clients.CommonClientConfigs;
|
||||||
import org.apache.kafka.clients.producer.Callback;
|
import org.apache.kafka.clients.producer.Callback;
|
||||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||||
|
@ -61,6 +54,13 @@ import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.maxmind.geoip2.model.CityResponse;
|
import com.maxmind.geoip2.model.CityResponse;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.data.BlackCard;
|
||||||
|
import net.socialgamer.cah.data.CardSet;
|
||||||
|
import net.socialgamer.cah.data.WhiteCard;
|
||||||
|
import net.socialgamer.cah.db.PyxBlackCard;
|
||||||
|
import net.socialgamer.cah.db.PyxCardSet;
|
||||||
|
import net.socialgamer.cah.db.PyxWhiteCard;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metrics implementation that sends all data to an Apache Kafka topic.
|
* Metrics implementation that sends all data to an Apache Kafka topic.
|
||||||
|
@ -70,7 +70,9 @@ import com.maxmind.geoip2.model.CityResponse;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class KafkaMetrics implements Metrics {
|
public class KafkaMetrics implements Metrics {
|
||||||
|
|
||||||
private static final String metricsVersion = "0.1";
|
// 0.1: initial version
|
||||||
|
// 0.2: added cardDealt
|
||||||
|
private static final String metricsVersion = "0.2";
|
||||||
private static final Logger LOG = Logger.getLogger(KafkaMetrics.class);
|
private static final Logger LOG = Logger.getLogger(KafkaMetrics.class);
|
||||||
|
|
||||||
private final ProducerCallback callback = new ProducerCallback();
|
private final ProducerCallback callback = new ProducerCallback();
|
||||||
|
@ -367,4 +369,27 @@ public class KafkaMetrics implements Metrics {
|
||||||
|
|
||||||
send(getEventMap("roundComplete", data));
|
send(getEventMap("roundComplete", data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cardDealt(final String gameId, final String sessionId, final WhiteCard card,
|
||||||
|
final long dealSeq) {
|
||||||
|
trace("%s, %s, %s, %d", gameId, sessionId, card, dealSeq);
|
||||||
|
|
||||||
|
final Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("gameId", gameId);
|
||||||
|
data.put("sessionId", sessionId);
|
||||||
|
data.put("dealSeq", dealSeq);
|
||||||
|
|
||||||
|
final Map<String, Object> whiteCardData = new HashMap<>();
|
||||||
|
// same re: more custom deck sources
|
||||||
|
whiteCardData.put("isCustom", !(card instanceof PyxWhiteCard));
|
||||||
|
whiteCardData.put("isWriteIn", card.isWriteIn());
|
||||||
|
// negative IDs would be custom: either blank or cardcast. they are not stable.
|
||||||
|
whiteCardData.put("id", card.getId());
|
||||||
|
whiteCardData.put("watermark", card.getWatermark());
|
||||||
|
whiteCardData.put("text", card.getText());
|
||||||
|
data.put("card", whiteCardData);
|
||||||
|
|
||||||
|
send(getEventMap("cardDealt", data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2017, Andy Janata
|
* Copyright (c) 2017-2018, Andy Janata
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
@ -29,12 +29,12 @@ import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.maxmind.geoip2.model.CityResponse;
|
||||||
|
|
||||||
import net.socialgamer.cah.data.BlackCard;
|
import net.socialgamer.cah.data.BlackCard;
|
||||||
import net.socialgamer.cah.data.CardSet;
|
import net.socialgamer.cah.data.CardSet;
|
||||||
import net.socialgamer.cah.data.WhiteCard;
|
import net.socialgamer.cah.data.WhiteCard;
|
||||||
|
|
||||||
import com.maxmind.geoip2.model.CityResponse;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect metrics about card plays, and correlate them with (anonymized) user data.
|
* Collect metrics about card plays, and correlate them with (anonymized) user data.
|
||||||
|
@ -58,4 +58,6 @@ public interface Metrics {
|
||||||
|
|
||||||
void gameStart(String gameId, Collection<CardSet> decks, int blanks, int maxPlayers,
|
void gameStart(String gameId, Collection<CardSet> decks, int blanks, int maxPlayers,
|
||||||
int scoreGoal, boolean hasPassword);
|
int scoreGoal, boolean hasPassword);
|
||||||
|
|
||||||
|
void cardDealt(String gameId, String sessionId, WhiteCard card, long dealSeq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2017, Andy Janata
|
* Copyright (c) 2017-2018, Andy Janata
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
@ -27,15 +27,15 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.socialgamer.cah.data.BlackCard;
|
|
||||||
import net.socialgamer.cah.data.CardSet;
|
|
||||||
import net.socialgamer.cah.data.WhiteCard;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.maxmind.geoip2.model.CityResponse;
|
import com.maxmind.geoip2.model.CityResponse;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.data.BlackCard;
|
||||||
|
import net.socialgamer.cah.data.CardSet;
|
||||||
|
import net.socialgamer.cah.data.WhiteCard;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A no-op metrics implementation. All data are logged at TRACE then discarded.
|
* A no-op metrics implementation. All data are logged at TRACE then discarded.
|
||||||
|
@ -84,4 +84,10 @@ public class NoOpMetrics implements Metrics {
|
||||||
LOG.trace(String.format("roundJudged(%s, %s, %s, %s, %s, %s)", gameId, roundId, judgeSessionId,
|
LOG.trace(String.format("roundJudged(%s, %s, %s, %s, %s, %s)", gameId, roundId, judgeSessionId,
|
||||||
winnerSessionId, blackCard, cards));
|
winnerSessionId, blackCard, cards));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cardDealt(final String gameId, final String sessionId, final WhiteCard card,
|
||||||
|
final long dealSeq) {
|
||||||
|
LOG.trace(String.format("cardDealt(%s, %s, %s, %d)", gameId, sessionId, card, dealSeq));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue