Experimental: Logging Extension - NetLogo/Tortoise GitHub Wiki

The logging extension is intended for model authors to use to log actions and values throughout the run of a NetLogo Web model. There is then the difficulty of getting a hold of the log file that is created with this extension, which is best remedied through using the http-req extension (which will be demonstrated below).

This extension's four primitives are as follows:

  • logging:clear-logs (discard the accumulated logs)
  • logging:all-logs (read the list of accumulated log entries)
  • logging:log-message (takes the string that you give it and stores it in the logs)
  • logging:log-globals (if given no arguments, logs all globals; otherwise, logs the globals whose names were passed as arguments to the primitive)

Here's a diff of how we can change the Slime model to add logging functionality:

+extensions [http-req logging]
+
 patches-own [chemical]

 to setup
   clear-all
+  logging:log-message (word "User name is: " (user-input "Hi, tell me a bit about yourself")) ; Getting data directly from user and logging it
   create-turtles population
   [ set color red
     set size 2  ;; easier to see
     setxy random-xcor random-ycor ]
   ask patches [ set chemical 0 ]
+  logging:log-message "Model is set up and ready to go." ; Simple message
+  logging:log-message date-and-time ; Logging the output of a simple primitive for a timestamp
+  (logging:log-globals) ; Logs all globals.  Needs parentheses around it whenever it has anything other than just one argument.
   reset-ticks
 end

 to go
+  logging:log-message (word "It is now tick " ticks " and the total amount of chemical is " (precision (sum [chemical] of patches) 2)) ; Message with dynamic value
+  (logging:log-globals "wiggle-angle" "sniff-angle") ; Logging just two globals
   ask turtles
   [ if chemical > sniff-threshold                  ;; ignore pheromone unless there's enough here
       [ turn-toward-chemical ]
@@ -24,6 +32,25 @@ to go
   tick
 end

+to show-logs
+  let opinion-trash-can (user-yes-or-no? (word "Do you dislike being monitored like this?\n\n" legible-logs)) ; Example of examining the logs while the model is running (not sure why you'd want to do that)
+end
+
+to send-logs
+  let response-triplet (http-req:post "MY_FAVORITE_URL" (word legible-logs) "text/plain") ; Use the http-req extension to send the data to a URL that accepts this logging data
+  ifelse (first response-triplet) = "200" [
+    show "logs successfully sent"
+    logging:clear-logs ; Clear the logs so the next batch we send isn't redundant at all
+  ] [
+    show "log transmission failed!"
+  ]
+end
+
+to-report legible-logs
+  report (reduce word map [log-line -> (word "  * " log-line "\n")] logging:all-logs)
+end
+
+
 to turn-toward-chemical  ;; turtle procedure
   ;; examine the patch ahead of you and two nearby patches;
   ;; turn in the direction of greatest chemical

Make sure that you change MY_FAVORITE_URL to your actual favorite URL for sending logs to.

If you run into errors with this approach, ensure that you understand the normal browser rules surrounding the Same-Origin Policy and Cross-Origin Resource Sharing, as the http-req extension is entirely subject to those rules, just like any other browser code. That said, the easiest solution to these sorts of problems is just to take your NetLogo Web model that makes and sends logs, and serve that model from the same domain that you send the logs to.