source: src/main/java/genius/core/logging/XmlLogger.java

Last change on this file was 255, checked in by Adel Magra, 5 years ago

Updated the user guide to contain information about the User class and elicitation functionality (Section 6, 7.3)

File size: 8.8 KB
Line 
1package genius.core.logging;
2
3import java.io.Closeable;
4import java.io.FileNotFoundException;
5import java.io.IOException;
6import java.io.OutputStream;
7import java.util.Date;
8import java.util.HashMap;
9import java.util.List;
10import java.util.Map;
11
12import javax.xml.stream.XMLStreamException;
13
14import genius.core.AgentID;
15import genius.core.Bid;
16import genius.core.actions.Offer;
17import genius.core.events.AgentLogEvent;
18import genius.core.events.MultipartyNegoActionEvent;
19import genius.core.events.NegotiationEvent;
20import genius.core.events.SessionEndedNormallyEvent;
21import genius.core.events.SessionFailedEvent;
22import genius.core.listener.Listener;
23import genius.core.misc.ExceptionTool;
24import genius.core.parties.NegotiationPartyInternal;
25import genius.core.session.Participant;
26import genius.core.session.Session;
27import genius.core.session.SessionConfiguration;
28import genius.core.utility.UtilitySpace;
29import genius.core.xml.Key;
30import genius.core.xml.XmlWriteStream;
31
32/**
33 * Creates a logger which will log {@link NegotiationEvent}s to a XML file. Logs
34 * the {@link SessionEndedNormallyEvent}.
35 */
36public class XmlLogger implements Listener<NegotiationEvent>, Closeable {
37
38 private XmlWriteStream stream;
39 /**
40 * map<key,value> where keys are the agent names. The values are the logs
41 * returned by the agent through an {@link AgentLogEvent}.
42 */
43 protected Map<String, Map<Object, Object>> agentLogs = new HashMap<>();
44 private int nrOffers = 0;
45 /**
46 * The agent that did the first action. Null until a first action was done
47 * in the current session or if there is no current session.
48 */
49 private AgentID startingAgent = null;
50
51 /**
52 * @param out
53 * {@link OutputStream} to write the log to. If this is a file,
54 * we recommend to use the extension ".xml". This logger becomes
55 * owner of this outputstream and will close it eventually.
56 * @param topLabel
57 * the top level label to use in the output file
58 * @throws FileNotFoundException
59 * @throws XMLStreamException
60 */
61 public XmlLogger(OutputStream out, String topLabel) throws FileNotFoundException, XMLStreamException {
62 stream = new XmlWriteStream(out, topLabel);
63 }
64
65 @Override
66 public void close() throws IOException {
67 try {
68 stream.flush();
69 } catch (XMLStreamException e) {
70 e.printStackTrace();
71 }
72 stream.close();
73 }
74
75 @SuppressWarnings({ "unchecked", "rawtypes" })
76 @Override
77 public void notifyChange(NegotiationEvent e) {
78 try {
79 if (e instanceof MultipartyNegoActionEvent) {
80 if (startingAgent == null) {
81 startingAgent = ((MultipartyNegoActionEvent) e).getAction().getAgent();
82 }
83 if (((MultipartyNegoActionEvent) e).getAction() instanceof Offer) {
84 nrOffers++;
85 }
86 } else if (e instanceof AgentLogEvent) {
87 // Map<String,String> to Map<Object,Object>...
88 agentLogs.put(((AgentLogEvent) e).getAgent(), (Map<Object, Object>) (Map) ((AgentLogEvent) e).getLog());
89 } else if (e instanceof SessionEndedNormallyEvent) {
90 stream.write("NegotiationOutcome", getOutcome((SessionEndedNormallyEvent) e));
91 reset();
92 } else if (e instanceof SessionFailedEvent) {
93 stream.write("NegotiationOutcome", getOutcome((SessionFailedEvent) e));
94 reset();
95 }
96 } catch (Exception e1) {
97 e1.printStackTrace();
98 }
99 }
100
101 /**
102 * Flush streams, reset counters etc.
103 *
104 * @throws XMLStreamException
105 */
106 private void reset() {
107 try {
108 stream.flush();
109 } catch (XMLStreamException e) {
110 e.printStackTrace();
111 }
112 // log done, reset the per-session trackers
113 agentLogs = new HashMap<>();
114 nrOffers = 0;
115 startingAgent = null;
116
117 }
118
119 /**
120 * Mostly duplicate from the other getOutcome but for failed sessions.
121 */
122 private Map<Object, Object> getOutcome(SessionFailedEvent e) {
123 Map<Object, Object> outcome = new HashMap<>();
124
125 Session session = e.getException().getSession();
126 outcome.put("exception", new ExceptionTool(e.getException()).getFullMessage());
127 outcome.put("currentTime", new Date().toString());
128 outcome.put("bids", nrOffers);
129
130 outcome.put("lastAction", session.getMostRecentAction());
131 outcome.put("deadline", session.getDeadlines().valueString());
132 outcome.put("runtime", session.getRuntimeInSeconds());
133 outcome.putAll(getPartiesReservationPoints(e.getException().getConfiguration()));
134
135 return outcome;
136 }
137
138 /**
139 *
140 * @param configuration
141 * the {@link SessionConfiguration}.
142 * @return list of reservation values for all participants in the
143 * configuration.
144 */
145 private Map<Object, Object> getPartiesReservationPoints(SessionConfiguration configuration) {
146 Map<Object, Object> outcome = new HashMap<>();
147
148 for (Participant party : configuration.getParties()) {
149 outcome.put(new Key("resultsOfAgent"), getReservationValue(party));
150 }
151
152 return outcome;
153
154 }
155
156 /**
157 * Get info based only on participant info. This is tricky as we need to
158 * consider many cases, especially because we get here because something is
159 * not quite ok in this info.
160 *
161 * @param party
162 * the {@link Participant}
163 * @return object containing as much info as we can get safely from this.
164 */
165 private Object getReservationValue(Participant party) {
166 Map<Object, Object> outcome = new HashMap<>();
167 outcome.put("agent", party.getStrategy().getUniqueName());
168 outcome.put("agentClass", party.getStrategy().getClassDescriptor());
169 outcome.put("utilspace", party.getProfile().getURL().getFile());
170 Double finalUtility = 0d;
171 Double discount = 0d;
172 Double discountedUtility = finalUtility;
173 try {
174 UtilitySpace utilspace = party.getProfile().create();
175 finalUtility = discountedUtility = utilspace.getReservationValue();
176 discount = utilspace.discount(1.0, 1.0);
177 } catch (Exception e) {
178 System.out.println("Failed to read profile of " + party + ". using 0");
179 }
180 outcome.put("discount", discount);
181 outcome.put("finalUtility", finalUtility);
182 outcome.put("discountedUtility", discountedUtility);
183
184 return outcome;
185 }
186
187 /**
188 * @param e
189 * the {@link SessionEndedNormallyEvent}
190 * @return the complete session outcome, including all agent outcomes
191 */
192 private Map<Object, Object> getOutcome(SessionEndedNormallyEvent e) {
193 Map<Object, Object> outcome = new HashMap<>();
194
195 Session session = e.getSession();
196 outcome.put("currentTime", new Date().toString());
197 outcome.put("startingAgent", startingAgent == null ? "-" : startingAgent.toString());
198 outcome.put("bids", nrOffers);
199
200 outcome.put("lastAction", session.getMostRecentAction());
201 outcome.put("deadline", session.getDeadlines().valueString());
202 outcome.put("runtime", session.getRuntimeInSeconds());
203 outcome.put("domain", e.getParties().get(0).getUtilitySpace().getDomain().getName());
204 outcome.put("finalOutcome", e.getAgreement() == null ? "-" : e.getAgreement());
205
206 if (e.getAgreement() != null) {
207 outcome.put("timeOfAgreement", session.getTimeline().getTime());
208 }
209
210 outcome.putAll(getAgentResults(e.getParties(), e.getAgreement()));
211 return outcome;
212 }
213
214 /**
215 *
216 * @param parties
217 * the parties in the negotiation
218 * @param bid
219 * the accepted bid, or null
220 * @return a Map containing all party results as key-value pairs
221 */
222 private Map<Object, Object> getAgentResults(List<NegotiationPartyInternal> parties, Bid bid) {
223 Map<Object, Object> outcome = new HashMap<>();
224
225 for (NegotiationPartyInternal party : parties) {
226 outcome.put(new Key("resultsOfAgent"), partyResults(party, bid));
227 }
228
229 return outcome;
230 }
231
232 /**
233 * Collect the results of a party in a map. This map will also contain the
234 * logs as done by the agent.
235 *
236 * @param party
237 * the party to collect the results for
238 * @param bid
239 * the accepted bid, or null
240 * @return a map containing the results
241 */
242 private Map<Object, Object> partyResults(NegotiationPartyInternal party, Bid bid) {
243 Map<Object, Object> outcome = new HashMap<>();
244 if (agentLogs.containsKey(party.getID())) {
245 outcome.putAll(agentLogs.get(party.getID()));
246 }
247 outcome.put("agent", party.getID());
248 outcome.put("agentClass", party.getParty().getClass().getName());
249 outcome.put("agentDesc", party.getParty().getDescription());
250 outcome.put("utilspace", party.getUtilitySpace().getName());
251 outcome.put("discount", party.getUtilitySpace().discount(1.0, 1.0));
252 outcome.put("totalUserBother", (party.getUser()!=null) ? party.getUser().getTotalBother() : 0.0);
253 outcome.put("finalUtility", party.getUtility(bid));
254 outcome.put("discountedUtility", party.getUtilityWithDiscount(bid));
255 outcome.put("userUtility", (party.getUser()!=null) ? party.getUtilityWithDiscount(bid)-party.getUser().getTotalBother():party.getUtilityWithDiscount(bid));
256
257 return outcome;
258 }
259
260}
Note: See TracBrowser for help on using the repository browser.