2013-06-12 58 views
5

Tôi đang làm việc với việc giám sát ứng dụng Erlang và tôi hiện đang cố gắng xác định thời gian một PID cụ thể đang chạy. Dấu thời gian tuyệt đối hoặc thời gian sẽ làm việc cho tôi, nhưng tôi không thấy một trong các bit dữ liệu đó trong process_info hoặc thông qua mô-đun sys. Có cách nào để có được thông tin này từ bên trong máy ảo Erlang không?Có xóa dữ liệu khi quá trình bắt đầu không?

Tôi có thể nhận được thời gian bắt đầu của máy ảo tổng thể từ lệnh ps, nhưng điều đó không có bất kỳ khả năng hiển thị nào của các quy trình Erlang riêng lẻ.

Edit:

tôi đã nhận thấy rằng khi tai nạn VM, erl_crash.dump chứa một dấu thời gian bắt đầu cho mỗi quá trình, vì vậy tôi biết nó ở trong đó!

+0

Cách khác (và có thể nói rõ ràng): Bạn có thể duy trì ngày bắt đầu trong trạng thái tiến trình (trong 'gen_server: init') và trả về sự khác biệt với' erlang: now' khi được hỏi. –

+0

Thứ hai, lưu rằng bạn nên sử dụng 'os: dấu thời gian/0' thay vì' erlang: now/0'. 'now/0' tiếc là cần phải có được một khóa toàn cầu để đảm bảo rằng nó trở lại là đơn điệu tăng và độc đáo. – troutwine

+0

Tôi rất muốn làm điều đó, nhưng nó không phải là ứng dụng của tôi, tôi chỉ giám sát nó, vì vậy tôi không thể thực hiện thay đổi trong bản thân ứng dụng. Tôi bắt đầu một máy ảo thứ hai và gửi lệnh qua rpc: call. – Joe

Trả lời

2

tl; dr: có, nhưng bạn không thể truy cập được.

Nếu bạn đào sâu vào mã nguồn OTP tại https://github.com/erlang/otp, bạn sẽ tìm thấy (bằng cách tìm kiếm "erl_crash") mà tệp chịu trách nhiệm viết đổ đổ được gọi là erts/emulator/beam/break.c.

Tìm kiếm tệp đó để "bắt đầu" (cả hai đều là phỏng đoán tốt và nó xuất hiện trong bãi chứa sự cố) sẽ đưa bạn đến lines 248-249 (tất cả các số dòng dựa trên thẻ OTP-18.3.1), trông giống như này:

approx_started = (time_t) p->approx_started; 
erts_print(to, to_arg, "Started: %s", ctime(&approx_started)); 

Tìm kiếm phần còn lại của mã nguồn cho approx_started cho thấy nó được khai báo trong erts/emulator/beam/erl_process.h như một thành viên của struct process. Đó là được viết trong erts/emulator/beam/erl_process.c. Các chỉ đặt nó là đọc là trong break.c, khi viết đổ sụp đổ.

Vì vậy, có, Erlang hiện ghi lại thời gian (ước tính) mà quá trình đã được bắt đầu. Nhưng, không, bạn không thể đến được.

Tôi không biết tại sao nó "gần đúng".

1

Tôi đã tìm kiếm trong thanh công cụ: start(). quá trình giám sát và không nhìn thời gian còn sống hoặc thời gian init, nhưng nó rất dễ dàng để thực hiện. Trong từ điển của quá trình bạn có thể lưu một giá trị khi init và rằng quá trình này có thể đáp ứng với quá trình khác về giá trị này.

Để biết giá trị đã đọc trong quá trình từ điển, bạn có thể sử dụng get/1 và để lưu sử dụng put/2 (khóa đầu tiên và giá trị thứ hai).

Trả lời các quy trình khác về giá trị này giống với các phản hồi khác, v.v.

+0

Điều này chắc chắn sẽ hoạt động, nhưng sẽ yêu cầu thay đổi bản thân ứng dụng. Tôi có thể gửi yêu cầu này làm yêu cầu tính năng nhưng tôi không thể tự mình thực hiện thay đổi đó. – Joe

+0

Nếu bạn cần điều này cho một ứng dụng mà không phát triển bạn và bạn sử dụng từ aplication của bạn, tôi khuyên bạn nên gửi này như là tính năng nhưng không để phát triển aplication khác để phát triển Erlang VM. Tôi nghĩ điều đó thật thú vị. – JHG

3

Viết quy trình quản lý việc này. Vì bạn có thể tìm thấy PID của quy trình đã cho, bạn cũng có thể đặt monitor trong quá trình này. Sau đó, nếu quá trình này bị lỗi, bạn sẽ nhận được một tin nhắn trong hộp thư của bạn.

Tôi đoán đây có thể là cơ sở cho giải pháp cho bạn.

+0

Vâng, đây là một cách tuyệt vời để được thông báo khi PID bị chết. Nhưng tôi cũng đang cố gắng tìm ra khi nó bắt đầu. – Joe

Các vấn đề liên quan