I am currently observing traces of Erlang programs (using the Erlang:trace function), specifically the YAWS web server, although my problem may not be limited to this particular program.
Basically, when I attempt to trace some processes and output these traces, the following errors are displayed:
=ERROR REPORT==== 30-Mar-2014::15:48:25 ===
Failed to open trace "trace.<0.4084.0>.traffic": "I/O error"
=ERROR REPORT==== 30-Mar-2014::15:48:25 ===
Failed to open trace "trace.<0.4085.0>.traffic": "I/O error"
=ERROR REPORT==== 30-Mar-2014::15:48:26 ===
Failed to open trace "trace.<0.4086.0>.traffic": "I/O error"
I would appreciate any insight into why this error is occurring and how it can be solved.
Thanks!
EDIT:
This is the code I am using:
looper()->
receive
P-> io:format(" trace msg: ~p ~n", [P])
end,
looper().
tracer2(Pid)->
erlang:trace(Pid,true,[set_on_spawn, send, 'receive']),
looper().
In the cmd, I first enter: ybed_sup:start_link() , then enter tracer2(PID) passing the PID of the process executing the function yaws_server:acceptor as a parameter.
At first, traces are printed correctly, but then this process dies and new processes with the functon yaws_server:acceptor are spawned, after which only the error messages show.
I think you might be confusing Erlang tracing and the tracing capabilities Yaws provides for HTTP requests. They are very different things.
The error you're seeing is caused by Yaws being unable to open the files mentioned in your error messages (for example, trace.<0.4084.0>.traffic), which by default are opened in the logdir specified in the yaws.conf file. You can read more about this near the top of the yaws.conf documentation or in the yaws.conf.5 man page that's part of your Yaws installation.
After your EDIT:
I fully agree with Steve Vinoski answer.
Few notes:
with current logic you "freeze" you shell (cmd), you might want spawn a new process for loop/0 function
if you just would like to simply debug your system try using dbg module
if trace/2 function would fail you would get little different error message; something similar to
** exception error: bad argument
in function erlang:trace/3
called as erlang:trace(a,b,c)
so you can assume code you wrote works just fine
(as far as I understand you) you're tracing process that is spawning yaws acceptor; make sure that you turn on tracing before acceptor is spawned, or pass to your trace2/1 function pid returned from yaws_server:acceptor
And finally make sure that you configuration is ok. From what you are describing your log_dir might not exist (or you could forget to add flag allowing to create folder), or you might not have permission to write in this directory.
Related
I am writing a small program in Progress that needs to write an error message to the system's standard error. What ways, simple if at all possible, can I use to print to standard error?
I am using OpenEdge 11.3.
When on Windows (10.2B+) you can use .NET:
System.Console:Error:WriteLine ("This is an error message") .
together with
prowin32 2> stderr.out
Progress doesn't provide a way to write to stderr - the easiest way I can think of is to output-through an external program that takes stdin and echoes it to stderr.
You could look into LOG-MANAGER:WRITE-MESSAGE. It won't log to standard output or standard error, but to a client-specific log. This log should be monitored in any case (specifically if the client is an application server).
From the documentation:
For an interactive or batch client, the WRITE-MESSAGE( ) method writes the log entries to the log file specified by the LOGFILE-NAME attribute or the Client Logging (-clientlog) startup parameter. For WebSpeed agents and AppServer servers, the WRITE-MESSAGE() method writes the log entries to the server log file. For DataServers, the WRITE-MESSAGE() method writes the log entries to the log file specified by the DataServer Logging (-dslog) startup parameter.
LOG-MANAGER:WRITE-MESSAGE("Got here, x=" + STRING(x), "DEBUG1").
Will write this in the log:
[04/12/05#13:19:19.742-0500] P-003616 T-001984 1 4GL DEBUG1 Got here, x=5
There are quite a lot of options regarding the LOG-MANAGER system, what messages to display, where the file is placed, etc.
There is no easy way, but in Unixen you can always do something like this using OUTPUT THROUGH (untested):
output through "cat >&2" no-echo unbuffered.
Alternatively -- and this is tested -- if you just want error messages from a batch-mode program to go to standard out then
output through "tee" ...
...definitely works.
There's some process started with Task.Supervisor.start_child, if something went wrong Elixir (Erlang) prints error message like this:
23:56:06.257 [error] Task #PID<0.216.0> started from #PID<0.137.0> terminating
It's hard to understand what process crashed. I wonder if there's a way to give a meaningful auto-generated names to processes? So the error will be more descriptive, like:
23:56:06.257 [error] Task #PID-REQUEST-HANDLER<0.216.0> started from #PID-SOCKET-LOOP<0.137.0> terminating
You can name each desired process with register/2 function:
Erlang:
register(RegName, PidOrPort) -> true
Elixir:
register(pid | port, atom) :: true
Then what you need is implementing your logger to use process_info(PID, registered_name) function to get the registered name of the desired process by its PID and formatting the log text with that name.
Update: Also it is good to know that error_logger is an event manager (gen_event). Error, warning, crash, progress and info events are sent to the error logger from the Erlang runtime system and the different Erlang/OTP applications. It has some default event handlers, as well as sasl which is an OTP application that adds more logging features to your application. You can also write your own event handler and add it to error_logger event manager.
I had ejabberd 13.12, all works great until I physically moved server machine to another network, then jabber server start encounting crashes. (the same types and details of networks)
CRASH REPORT Process <0.4260.0> with 0 neighbours exited with reason: call to undefined function
ejabberd_socket:get_conn_type({socket_state,gen_tcp,#Port<0.5852>,<0.4259.0>}) in p1_fsm:terminate/7 line 733
2014-01-23 09:34:42.548 [error] <0.330.0> Supervisor ejabberd_c2s_sup had child undefined started with
{ejabberd_c2s,start_link,undefined} at <0.4260.0> exit with reason call to undefined function
ejabberd_socket:get_conn_type({socket_state,gen_tcp,#Port<0.5852>,<0.4259.0>}) in context child_terminated
after machine migration the statuses of users was changed randomly.
I tried reinstall jabber server and I used ejabberd 2.1.13 compiled from scratch - what give me the same errors while using jabber.
function is:
get_conn_type(StateData) ->
case (StateData#state.sockmod):get_sockmod(StateData#state.socket) of
gen_tcp -> c2s;
p1_tls -> c2s_tls;
ezlib ->
case ezlib:get_sockmod((StateData#state.socket)#socket_state.socket) of
gen_tcp -> c2s_compressed;
p1_tls -> c2s_compressed_tls
end;
ejabberd_http_poll -> http_poll;
ejabberd_http_bind -> http_bind;
_ -> unknown
end.
I want understand this function (good pythoner, never erlang) and add hack or pinpoint the issue: is sth ejabberd specific or sth with sockets (but others network tools/services works perfect).
a) how can I insert to that function interactive debugger and get interactive introspection of stack and variables there.
The error message you're seeing says that the get_conn_type function doesn't exist in the ejabberd_socket module. And this is true; in the standard ejabberd distribution, get_conn_type lives in the ejabberd_c2s module.
If you are positive that neither you nor anyone else has modified the sources, then I would check your installation of Erlang. Perhaps it's broken, or you're using different versions to compile and run the code.
I have a process running on node2. Can I register this process using register/2 on node1? Basically I am trying to do this:
register(process_name, spawn_link(node2, module, function, [Arg1, Arg2]))
I get this error:
** exception error: bad argument
in function register/2
called as register(process_name, <5902.92.0>)
When I register a process local to node1, this works perfectly fine. I could not find any documentation which prevents registration of processes of other nodes.
Thanks.
Actually it is well documented, and the expected behaviour as register() is for local process registration.
http://www.erlang.org/doc/man/erlang.html#register-2
Failure: badarg if PidOrPort is not an existing, local process or port, [...]
If you want global registration across your cluster, read http://erlang.org/doc/man/global.html
Note that if you use standard OTP behaviours, (gen_server, etc) most of the time you don't need to use the global module directly.
Warning: erlang n00b ahead.
I'm trying to get a grasp of erlang, and just trying a basic hello world application with cowboy. I'm simulating an error, basically returning an invalid value somewhere in my code, and trying to interpret the error, which is:
=ERROR REPORT==== 11-Jul-2013::15:45:00 ===
Error in process <0.167.0> with exit value: {{try_clause,{ok, {http_req,#Port<0.3619>,ranch_tcp,keepalive,<0.167.0>,<<3 bytes>>,'HTTP/1.1', {{127,0,0,1},60312},<<9 bytes>>,undefined,8081,<<1 byte>>,undefined,<<0 bytes>>,undefined,[],[{<<10 bytes>>,<<11 bytes>>},{<<4 bytes>>,<<14 bytes>>},{<<6 bytes>>,<<3 bytes>>}],[],undefined,[],waiting,undefined,<<0 bytes>>,false,waiting,[],<<0 bytes>>,undefined}}}, [{cowboy_handler,handler_init,4,[...
I've setup my application with rebar, and I'm running it with:
erl -pa ebin deps/*/ebin -s myapp
As you can see, the error ends with "..." which makes me think it is being truncated. Is there any way to print the full report?
And, is there any way to make it pretty-print it?
Thanks!
What you see is sasl's tty handler. It formats and writes reports to console. During formatting it could cut some useful data.
To avoid it, use error_logger_mf_h handler like this:
Create app.config file to pass some vars to sasl:
[
{sasl, [
{sasl_error_logger, {file, "sasl.log"}},
{errlog_type, all},
{error_logger_mf_dir, "."}, % Log directory
{error_logger_mf_maxbytes, 10485760}, % 10 MB max file size
{error_logger_mf_maxfiles, 5} % 5 files max
]}
].
Then bring erl node with started sasl. Logs will be printed into sasl.log
erl -boot start_sasl -config app.config
The error message is truncated by the Erlang emulator, so there is no way to get the full message from sasl. There is an undocumented switch that you can use to see more of the message. "erl +# 400" truncate at 400 instead of 200 characters.
More details: http://erlang.org/pipermail/erlang-questions/2014-October/081442.html
I believe there is no easy way of telling sasl to not truncate the error report.
What you could do is create your own handler for the reports and log the error in a way that it is not truncated. (e.g. io:format("~p", [Error])).
Look here for an exemple of custom report handler.
And you must add your custom handler as a subscriber of error reports:
error_logger:add_report_handler(?MODULE, []).
Or you could use a logging library that supports error_logger.