2
$\begingroup$

I am testing using CloudDeploy[APIFunction[...]]. I can not find any info about real time logging.

If there is any problem happening with the cloud deployed API, how can I debug it?

$\endgroup$
3
  • 1
    $\begingroup$ No, there isn't any out of the box feature for logging afaik. $\endgroup$
    – Kuba
    Jan 14, 2019 at 19:29
  • $\begingroup$ @kuba, Thanks for answer. $\endgroup$ Jan 14, 2019 at 19:47
  • $\begingroup$ p.s. there are server level logs but I don't think they are accessible in the public cloud. $\endgroup$
    – Kuba
    Jan 15, 2019 at 22:45

1 Answer 1

2
$\begingroup$

I will show you a small piece of code you can use as a starting point, it is already nice enough.

Just compose withLogger[apiPath] with your APIFunction's function. And initialize the log file.

Like this:

With[{apiPath = "api/foo"},

 CloudPut["#API init " <> DateString[], apiPath <> ".log"];

 CloudDeploy[
   APIFunction[
     {"x" -> "Integer"}
   , withLogger[apiPath] @ Check[ (*!*)
       Print["start"]
     ; 1 / Echo[#x]
     , GenerateHTTPResponse[Echo @ HTTPErrorResponse[500]]
     ] &
   ]
 , apiPath
 , Permissions -> "Public"
 ]

]

(*! - only that line matters, everything else is only to show the point*)

withLogger is defined at the end of the post. Here is an example:

enter image description here

withLogger[parentPath_] := Function[expr,
  Module[{logFile, log, res, timeMark},

   timeMark = AbsoluteTime[];

   logFile = parentPath <> ".log";

   Quiet@OpenAppend[logFile, FormatType -> (OutputForm), 
     PageWidth -> Infinity];

   log[type : "INFO" | "DEBUG" | "MESSAGE" : "INFO", msg__] := Write[
     logFile,
     DateString[{"ISODate", " ", "Time", ".", "Millisecond", " "}],
     $SessionID, " ",
 $RequesterWolframID, " ",
     type, " ",
     Sequence @@ Riffle[{msg}, " "]
     ];

   Block[{Print, Echo, messageString},
    Print = log;
    Echo[input_, label_: "", pipe_: Identity] := CompoundExpression[
      Print["INFO", label /. "" :> (## &[]), pipe@input],
      input
      ];

    messageString[
      Hold[Message[msg : MessageName[head_, name_], args___], _]] := 
     ToString[StringForm[msg /. Messages[head], args]];

    Internal`HandlerBlock[
     {"Message", If[Last[#], Print["MESSAGE", messageString[#]]] &},
     Print["--------------- API CALL EXECUTION --------------"];
     res = expr;
     Print@
      StringTemplate["Kernel evaluation time `` [s]"][
       AbsoluteTime[] - timeMark];
     res
     ]
    ]
   ]
  , HoldAllComplete
  ]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.