Updated logtool

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Updated logtool

grampajohn
Administrator
Dear colleagues -

Today I pushed out a refactoring of the Power TAC logtool. Although there's more development to be done on it, I think it's ready for some serious use and feedback. You no longer need a server source environment to use it, or a special branch of common, because it works with the deployed 1.0.0-SNAPSHOT components, while remaining compatible with the state log files generated in the September and December tournaments.

The refactoring separates the logtool core from the example set. You can get it by cloning or pulling down a zip of the powertac-tools repo. In either case, you do not need to do anything with the logtool directory, because that's compiled and deployed and maven will find it. All you need to do is use the three classes in logtool-examples, along with the pom.xml file, as a reference for building your own data-extraction tools. Instructions for use are in the README files.

One example that would be very helpful would be an analyzer that extracts state-log data and pushes it into a sql database. If you are willing to volunteer, I would be happy to help out if you get stuck.

Cheers -

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

iBuljevic
Hi John,

I've tried to run every logtool example (with state log from last tournament, and from local games on server version 0.6.3 and 1.0.0), and it doesn't seem to work for me. Every time I get similar errors in logtool.trace:

0 INFO  logtool.LogtoolCore: Reading file log2.state
135 ERROR common.DomainObjectReader: Exception calling method withSimulationBaseTime on args [Ljava.lang.String;@2e771a72
150 ERROR common.DomainObjectReader: could not parse Instant 1255132800000
150 ERROR common.DomainObjectReader: Exception calling method withSimulationBaseTime on args [Ljava.lang.String;@751fcae6
176 INFO  common.DomainObjectReader: time set to 2009-10-10T00:00:00.000Z
179 INFO  common.DomainBuilder: add broker default broker
179 ERROR common.DomainObjectReader: Cannot find method setLocal for class org.powertac.du.DefaultBroker
180 ERROR common.DomainObjectReader: Exception calling method withSimulationBaseTime on args [Ljava.lang.String;@2037f84c
180 ERROR common.DomainObjectReader: could not parse Instant 1255132800000
180 ERROR common.DomainObjectReader: Exception calling method withSimulationBaseTime on args [Ljava.lang.String;@3a8e561a
182 INFO  common.DomainObjectReader: time set to 2009-10-10T00:00:00.000Z
183 ERROR common.DomainObjectReader: Cannot find instance for id 2
184 INFO  common.DomainObjectReader: time set to 2009-10-25T00:00:00.000Z
184 ERROR common.DomainObjectReader: Cannot find instance for id 3
184 ERROR common.DomainObjectReader: Cannot find instance for id 4
184 ERROR common.DomainObjectReader: Cannot find instance for id 5
187 INFO  common.DomainObjectReader: ignoring org.powertac.common.Rate$ProbeCharge
209 ERROR common.DomainObjectReader: Cannot find method setTariffId for class org.powertac.common.Rate
209 INFO  common.DomainObjectReader: ignoring org.powertac.common.Tariff
210 INFO  common.DomainObjectReader: ignoring org.powertac.common.Rate$ProbeCharge
210 ERROR common.DomainObjectReader: Cannot find method setTariffId for class org.powertac.common.Rate
211 INFO  common.DomainObjectReader: ignoring org.powertac.common.Tariff
211 ERROR common.DomainObjectReader: Cannot find instance for id 12
217 ERROR common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
219 INFO  common.DomainBuilder: add broker nsp1a
219 ERROR common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
220 INFO  common.DomainBuilder: add broker nsp1b
220 ERROR common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
220 INFO  common.DomainBuilder: add broker nsp2a
220 ERROR common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
221 INFO  common.DomainBuilder: add broker nsp2b
221 ERROR common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
221 INFO  common.DomainBuilder: add broker gas1
221 ERROR common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
222 INFO  common.DomainBuilder: add broker gas2
223 ERROR common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
223 INFO  common.DomainBuilder: add broker backup
230 ERROR common.DomainObjectReader: Cannot find instance for id 27
230 ERROR common.DomainObjectReader: Cannot find instance for id 28
230 ERROR common.DomainObjectReader: Cannot find instance for id 29
230 ERROR common.DomainObjectReader: Cannot find instance for id 30
230 ERROR common.DomainObjectReader: Cannot find instance for id 31
230 ERROR common.DomainObjectReader: Cannot find instance for id 32
230 ERROR common.DomainObjectReader: Cannot find instance for id 33
232 ERROR common.DomainObjectReader: Cannot find instance for id 36
232 ERROR common.DomainObjectReader: Cannot find instance for id 37
233 ERROR common.DomainObjectReader: Cannot find instance for id 41
237 ERROR common.DomainObjectReader: Cannot find instance for id 49
238 ERROR common.DomainObjectReader: Cannot find instance for id 57
239 ERROR common.DomainObjectReader: Cannot find instance for id 65
241 ERROR common.DomainObjectReader: Cannot find instance for id 73
242 ERROR common.DomainObjectReader: Cannot find instance for id 81
243 ERROR common.DomainObjectReader: Cannot find instance for id 89
245 ERROR common.DomainObjectReader: Cannot find instance for id 97
Please can you suggest some solution to fix this problem?

Best regards,
Ivo Buljevic
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
Thanks for the detailed info. I will look at this when I get some time, probably later this week.

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

jurica.babic
Hi John,

Any update on this issue?

Thanks much.

Jurica
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
On 03/22/2013 11:53 AM, jurica.babic [via Power TAC Developers] wrote:
> Hi John,
>
> Any update on this issue?

Not yet. It's next on my list. I'll try to get to it today or tomorrow.

John


Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
In reply to this post by iBuljevic
iBuljevic wrote
I've tried to run every logtool example (with state log from last tournament, and from local games on server version 0.6.3 and 1.0.0), and it doesn't seem to work for me. Every time I get similar errors in logtool.trace:

0 INFO  logtool.LogtoolCore: Reading file log2.state
135 ERROR common.DomainObjectReader: Exception calling method withSimulationBaseTime on args [Ljava.lang.String;@2e771a72
...
245 ERROR common.DomainObjectReader: Cannot find instance for id 97
Please can you suggest some solution to fix this problem?
I just tried it with a logfile from the tournament this week (game 13), and it works fine. Could you perhaps point me to a specific logfile for which it does not work?

Thanks.

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

jurica.babic
Well I am experiencing similar problems with the logtool.

In my case the tool will fail when it attempts to read the first WeatherReport object running ImbalanceStats:
167526:org.powertac.common.WeatherReport::221::new::360::5.3::4.0::210.0::1.0

It will complain about the missing object with id 360.

It seems to me that the problem lies in resolving the right constructor for some of objects.

Take WeatherReport class for example. This class has two possible constructors. The difference between those two constructors are in the way timeslot information is declared (you can put timeslot index with int or you can use the "real" Timeslot object).

I think this is where the problem starts (at least in my case anyway). The logtool uses a greedy approach for finding the appropriate constructor for an object. In my case, it will always check/find the constructor which uses "Timeslot timeslot" as the first parameter, not "int timeslot".

Because of that, the logtool will enter this code in DomainObjectReader [method: private Object resolveSimpleArg (Class<?> clazz, String arg) throws MissingDomainObject)]
------------------------------------------------
   else {
            // it's a domain object, but we cannot resolve it
            // -- this should not happen.
            log.info("Missing domain object " + key);
           throw new MissingDomainObject("missing object id=" + key);
          }
------------------------------------------------

Interpretation: Because Timeslot starts with "org.powertac" and has getId method, the logtool will attempt to find the object from idMap (which is managed by the logtool). As this object does not exist, it will throw an exception and will break the logtool.

After I have modified the logtool in order to give it a chance to try with the right constructor (i.e., the one with "int timeslot" as the first parameter) the logtool is able to work as it should have.

Did you experience the same problem? If not, perhaps your machine will always greedily find the appropriate constructor and thus won't fail (this can happen because there is no way to influence the order of retrieved constructor candidates).

Thoughts?

Cheers,
Jurica
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

jurica.babic
UPDATE:

This quick fix works only for ImbalanceStats example so I would appreciate if someone can help us with the logtool.

Jurica
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
In reply to this post by jurica.babic
jurica.babic wrote
Well I am experiencing similar problems with the logtool.

In my case the tool will fail when it attempts to read the first WeatherReport object running ImbalanceStats:
167526:org.powertac.common.WeatherReport::221::new::360::5.3::4.0::210.0::1.0

It will complain about the missing object with id 360.

It seems to me that the problem lies in resolving the right constructor for some of objects.

Take WeatherReport class for example. This class has two possible constructors. The difference between those two constructors are in the way timeslot information is declared (you can put timeslot index with int or you can use the "real" Timeslot object).

I think this is where the problem starts (at least in my case anyway). The logtool uses a greedy approach for finding the appropriate constructor for an object. In my case, it will always check/find the constructor which uses "Timeslot timeslot" as the first parameter, not "int timeslot".
Hello, Jurica -

I will need your help to reproduce this problem. It works for me, with the two constructors. So I need to know exactly how you are running it, and ideally which logfile you are reading.

If you are running it with maven, then you need to do a complete local install, including the new version of common. If that's what you need to do, then perhaps I should go ahead with a full deploy today. I was going to hold off for a couple of days and see if anyone had problems.

If you are running with STS, then you need the latest common, and you have to force a re-build.

Thanks.

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

jurica.babic
Thanks for the info.

I have deleted all powertac-related files in my .m2 folder, made checkout of all the projects (master branch) and mvn installed them.

Now I have some more success but the logtool still does not work fully:
log: powertac-sim-13.state (from the trial)

MktPriceStats
Console output:
MDO on 2797007:org.powertac.common.Order::338670::new::21::910::-42.07508706584578::35.0
File output:
0KB

WeatherStats
Console output:
MDO on 2797007:org.powertac.common.Order::338670::new::21::910::-42.07508706584578::35.0
File output:
0KB

ImbalanceStats
Console output:
MDO on 2797007:org.powertac.common.Order::338670::new::21::910::-42.07508706584578::35.0
File output:
64KB

Logtool's tracelog says: "INFO  common.DomainObjectReader: Missing domain object 910"

-
Jurica
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
In reply to this post by jurica.babic
jurica.babic wrote
I think this is where the problem starts (at least in my case anyway). The logtool uses a greedy approach for finding the appropriate constructor for an object. In my case, it will always check/find the constructor which uses "Timeslot timeslot" as the first parameter, not "int timeslot".

Because of that, the logtool will enter this code in DomainObjectReader [method: private Object resolveSimpleArg (Class<?> clazz, String arg) throws MissingDomainObject)]
------------------------------------------------
   else {
            // it's a domain object, but we cannot resolve it
            // -- this should not happen.
            log.info("Missing domain object " + key);
           throw new MissingDomainObject("missing object id=" + key);
          }
------------------------------------------------

Interpretation: Because Timeslot starts with "org.powertac" and has getId method, the logtool will attempt to find the object from idMap (which is managed by the logtool). As this object does not exist, it will throw an exception and will break the logtool.
This is very close to a correct diagnosis. It turns out that when we removed timeslots from the message traffic, we also removed the id field from timeslots. As a result, timeslots log their index values as ids. But the original idea was that timeslots should not be logged at all. Unfortunately, there are several places where logged methods were taking timeslots instead of timeslot index values. I am cleaning those up. Ultimately, there will be a small edited needed in existing broker code, because findMarketPositionByTimeslot() now takes an int rather than a timeslot. Perhaps I can still overcome this and keep backward compatibility; I'll try.

This issue is #678.

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
Colleagues -

I believe issue #678 is resolved. The logtool now seems to read the tournament logs without failures, and it also reads the logs produced by this snapshot version. Updated server modules are deployed to the snapshot repo. Note that there were several changes in common, so you will almost certainly need to re-compile your brokers. I was able to find a way to fix it that does not force changes in broker code. However, the fix required that a few private and protected methods be made public so the logtool could get at them. They are labeled to let you know that they should only be used by the logtool; please don't break this convention without some discussion.

If you try the server, note that there appears to be a recent regression in the visualizer (see issue #679). You can use it to run boot and sim sessions, but the game display does not work in a local setup (without the tournament manager).

As always, please let me know if you have trouble with this snapshot.

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

iBuljevic
Hi John,

bad news.. I've just tried clean install on common module, server and logtool (I have also manually deleted local powertac m2 repository), but it still doesn't work. I tried this on two computers, same result - one test failed:
Failed tests:   readRRObject(org.powertac.logtool.common.DomainObjectReaderTest): bad exception org.powertac.logtool.common.MissingDomainObject: missing object id=42
I've managed to install logtool (with -DskipTests option), but still, there are some other problems.
When I import projects in eclipse and try to run any example, this is my log.trace:
0 INFO  logtool.LogtoolCore: Reading file log_13.state
42 INFO  common.DomainObjectReader: time set to 2009-02-16T00:00:00.000Z
45 INFO  common.DomainBuilder: add broker default broker
47 INFO  common.DomainObjectReader: time set to 2009-02-16T00:00:00.000Z
49 WARN  common.DomainObjectReader: Cannot find instance for id 2
49 INFO  common.DomainObjectReader: time set to 2009-03-03T00:00:00.000Z
50 WARN  common.DomainObjectReader: Cannot find instance for id 3
50 WARN  common.DomainObjectReader: Cannot find instance for id 4
50 WARN  common.DomainObjectReader: Cannot find instance for id 5
53 INFO  common.DomainObjectReader: ignoring org.powertac.common.Rate$ProbeCharge
60 INFO  common.DomainObjectReader: ignoring org.powertac.common.Tariff
60 INFO  common.DomainObjectReader: ignoring org.powertac.common.Rate$ProbeCharge
61 INFO  common.DomainObjectReader: ignoring org.powertac.common.Tariff
61 WARN  common.DomainObjectReader: Cannot find instance for id 12
66 WARN  common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
67 INFO  common.DomainBuilder: add broker nsp1a
67 WARN  common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
68 INFO  common.DomainBuilder: add broker nsp1b
68 WARN  common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
68 INFO  common.DomainBuilder: add broker nsp2a
68 WARN  common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
68 INFO  common.DomainBuilder: add broker nsp2b
68 WARN  common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
69 INFO  common.DomainBuilder: add broker gas1
69 WARN  common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
69 INFO  common.DomainBuilder: add broker gas2
69 WARN  common.DomainObjectReader: No default constructor for org.powertac.genco.Genco: java.lang.NoSuchMethodException: org.powertac.genco.Genco.<init>()
70 INFO  common.DomainBuilder: add broker backup
74 WARN  common.DomainObjectReader: Cannot find instance for id 27
75 WARN  common.DomainObjectReader: Cannot find instance for id 28
75 WARN  common.DomainObjectReader: Cannot find instance for id 29
75 WARN  common.DomainObjectReader: Cannot find instance for id 30
75 WARN  common.DomainObjectReader: Cannot find instance for id 31
75 WARN  common.DomainObjectReader: Cannot find instance for id 32
75 WARN  common.DomainObjectReader: Cannot find instance for id 33
77 WARN  common.DomainObjectReader: Cannot find instance for id 36
77 WARN  common.DomainObjectReader: Cannot find instance for id 37
78 WARN  common.DomainObjectReader: Cannot find instance for id 41
81 WARN  common.DomainObjectReader: Cannot find instance for id 49
83 WARN  common.DomainObjectReader: Cannot find instance for id 57
86 WARN  common.DomainObjectReader: Cannot find instance for id 65
87 WARN  common.DomainObjectReader: Cannot find instance for id 73
88 WARN  common.DomainObjectReader: Cannot find instance for id 81
90 WARN  common.DomainObjectReader: Cannot find instance for id 89
92 WARN  common.DomainObjectReader: Cannot find instance for id 97
94 WARN  common.DomainObjectReader: Cannot find instance for id 103
94 WARN  common.DomainObjectReader: Cannot find instance for id 104
94 WARN  common.DomainObjectReader: Cannot find instance for id 105
94 WARN  common.DomainObjectReader: Cannot find instance for id 106
95 WARN  common.DomainObjectReader: Cannot find instance for id 110
95 WARN  common.DomainObjectReader: Cannot find instance for id 111
95 WARN  common.DomainObjectReader: Cannot find instance for id 112
95 WARN  common.DomainObjectReader: Cannot find instance for id 113
95 WARN  common.DomainObjectReader: Cannot find instance for id 114
95 WARN  common.DomainObjectReader: Cannot find instance for id 115
96 WARN  common.DomainObjectReader: Cannot find instance for id 119
96 WARN  common.DomainObjectReader: Cannot find instance for id 120
96 WARN  common.DomainObjectReader: Cannot find instance for id 121
96 WARN  common.DomainObjectReader: Cannot find instance for id 122
97 WARN  common.DomainObjectReader: Cannot find instance for id 126
97 WARN  common.DomainObjectReader: Cannot find instance for id 127
97 WARN  common.DomainObjectReader: Cannot find instance for id 128
97 WARN  common.DomainObjectReader: Cannot find instance for id 129
98 WARN  common.DomainObjectReader: Cannot find instance for id 130
98 WARN  common.DomainObjectReader: Cannot find instance for id 131
98 WARN  common.DomainObjectReader: Cannot find instance for id 135
99 WARN  common.DomainObjectReader: Cannot find instance for id 136
99 WARN  common.DomainObjectReader: Cannot find instance for id 137
99 WARN  common.DomainObjectReader: Cannot find instance for id 138
99 WARN  common.DomainObjectReader: Cannot find instance for id 139
99 WARN  common.DomainObjectReader: Cannot find instance for id 140
100 WARN  common.DomainObjectReader: Cannot find instance for id 144
100 WARN  common.DomainObjectReader: Cannot find instance for id 145
100 WARN  common.DomainObjectReader: Cannot find instance for id 146
101 WARN  common.DomainObjectReader: Cannot find instance for id 147
102 WARN  common.DomainObjectReader: Cannot find instance for id 151
102 WARN  common.DomainObjectReader: Cannot find instance for id 152
103 WARN  common.DomainObjectReader: Cannot find instance for id 154
103 WARN  common.DomainObjectReader: Cannot find instance for id 155
103 WARN  common.DomainObjectReader: Cannot find instance for id 156
103 WARN  common.DomainObjectReader: Cannot find instance for id 157
105 WARN  common.DomainObjectReader: Cannot find instance for id 163
105 WARN  common.DomainObjectReader: Cannot find instance for id 164
105 WARN  common.DomainObjectReader: Cannot find instance for id 165
105 WARN  common.DomainObjectReader: Cannot find instance for id 166
106 WARN  common.DomainObjectReader: Cannot find instance for id 170
106 WARN  common.DomainObjectReader: Cannot find instance for id 171
107 WARN  common.DomainObjectReader: Cannot find instance for id 173
107 WARN  common.DomainObjectReader: Cannot find instance for id 174
107 WARN  common.DomainObjectReader: Cannot find instance for id 175
108 WARN  common.DomainObjectReader: Cannot find instance for id 176
109 WARN  common.DomainObjectReader: Cannot find instance for id 181
109 WARN  common.DomainObjectReader: Cannot find instance for id 185
111 WARN  common.DomainObjectReader: Cannot find instance for id 193
117 WARN  common.DomainObjectReader: Cannot find instance for id 201
118 WARN  common.DomainObjectReader: Cannot find instance for id 209
124 INFO  common.DomainBuilder: add broker Mertacor
124 INFO  common.DomainBuilder: add broker CrocodileAgent
125 INFO  common.DomainBuilder: add broker LARGEpower
125 INFO  common.DomainBuilder: add broker MLLBroker
125 INFO  common.DomainBuilder: add broker AstonTAC
128 INFO  common.DomainObjectReader: time set to 2009-03-03T00:00:00.000Z
130 INFO  common.DomainObjectReader: Missing domain object 360
Do you have any idea what can be the problem?

Best regards,
Ivo
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
iBuljevic wrote
bad news.. I've just tried clean install on common module, server and logtool (I have also manually deleted local powertac m2 repository), but it still doesn't work. I tried this on two computers, same result - one test failed:
Failed tests:   readRRObject(org.powertac.logtool.common.DomainObjectReaderTest): bad exception org.powertac.logtool.common.MissingDomainObject: missing object id=42
I've managed to install logtool (with -DskipTests option), but still, there are some other problems.
When I import projects in eclipse and try to run any example, this is my log.trace:
...
49 WARN  common.DomainObjectReader: Cannot find instance for id 2
...
128 INFO  common.DomainObjectReader: time set to 2009-03-03T00:00:00.000Z
130 INFO  common.DomainObjectReader: Missing domain object 360
Do you have any idea what can be the problem?
Ivo -

This is very strange. I just tried it again here, on two different machines, and it's working fine. You should not need to install anything but logtool at this point; I re-deployed common and all the server modules last night. The DomainObjectReaderTest does not fail for me.

The "bad exception" error in the test cound indicate that you are using an older version of common with the new logtool. The error is happening when trying to parse an Order, which at one time had the second argument as a timeslot id value, and now has a timeslot index instead. The test uses an index value of 42.

The WARN messages in the log are about RandomSeed instances; you can safely ignore those. The only bad item I see in the log is the "Missing domain object 360". I was getting that earlier, and I fixed it; 360 is almost certainly a timeslot index that is being interpreted as an object ID. That should not be happening.

It is possible that you are seeing these errors because of a difference in Java implementations. Order has two constructors, one of which takes a timeslot in the second position, the other a timeslot index. In DomainObjectReader.constructInstance(), the order in which constructors are tested could lead to this behavior. I will see if I can reproduce it locally. It might be necessary to modify the current "greedy" approach to finding the correct constructor.

Thanks for your patience on this.

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
In reply to this post by iBuljevic
Ivo -

Good news - I was able to reproduce your problem by reversing the order of constructors in Order. I have just pushed an update to logtool that handles this case correctly; the tests now pass with constructors in either order.

Cheers -

John
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

iBuljevic
Thanks John, it's working perfectly!

Cheers,
Ivo
Reply | Threaded
Open this post in threaded view
|

Re: Updated logtool

grampajohn
Administrator
iBuljevic wrote
Thanks John, it's working perfectly!
Thank you! You gave us the critical clue.

John