-
Notifications
You must be signed in to change notification settings - Fork 27
Experimental: Extensions
The following describes the grammar for defining an extension's .json
defs file.
type ArgType = "unit" ('void' type; only appears in return type; indicates that this is a command, not a reporter) | "agentset" | "agent" | "booleanblock" | "boolean" | "bracketed" | "codeblock" | "commandblock" | "command" | "linkset" | "link" | "list" | "nobody" | "numberblock" | "number" | "optional" | "otherblock" | "patchset" | "patch" | "readable" | "reference" | "reporterblock" | "reporter" | "string" | "symbol" | "turtleset" | "turtle" | "wildcard"
type PrimDef =
{
name: string (name in NetLogo)
, actionName: string (name of property in the `prims` field of the object exported by the extension in JavaScript)
, argTypes: array[ArgType | { type: ArgType, isRepeatable: boolean (default: false) }] (default: [])
, returnType: ArgType (default: "unit")
, isInfix: boolean (default: false)
, precedenceOffset: number (default: 0)
}
type ExtDef =
{
name: string
, prims: array[PrimDef]
}
This 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.