获取 运行 应用程序的自定义状态
Get custom status of a running application
我想获取 运行 申请的申请状态。例如:
# start my app
./my_app
# require status
./my_app status
# it prints information about the application
jobs waiting in queue : 120
processing jobs : 3414
jobs done : 300
number of bad request received : 120
[...]
目前我认为只有一种选择可以实现此结果:使用外部进程。
外部进程"speak"与主应用程序通过一个文件(它touch
一个新文件,所以主应用程序"knows"它必须准备状态报告),然后当状态报告准备好后,它发送回外部进程(通过文件),最后这个将状态打印到 cli。
但我个人觉得这个解决方案不太优雅。
您还有其他想法来实现这一目标吗?该应用程序是用 Golang 编写的,Go 中是否有任何技巧可以做到这一点?
文件系统不是为应用程序提供输入的唯一方式,还有许多其他方式,例如将数据发送到其标准输入,应用程序可以在端口上侦听传入连接或使用任何其他外围设备(如麦克风、传感器等)。
由于 Go 有一个内置的网络服务器,利用它可能很方便:Go 应用程序可以启动网络服务器(如果它还没有使用它),并在端口上侦听传入连接,当请求到来时,只需将状态作为简单文本或 HTML 格式发回。
这是一个例子:
package main
import (
"fmt"
"net/http"
)
var (
waiting = 120
processing = 3414
done = 300
)
func ServeStats(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%-22s : %d\n", "jobs waiting in queue", waiting)
fmt.Fprintf(w, "%-22s : %d\n", "processing jobs", processing)
fmt.Fprintf(w, "%-22s : %d\n", "jobs done", done)
}
func main() {
http.HandleFunc("/", ServeStats)
err := http.ListenAndServe("localhost:8081", nil)
if err != nil {
fmt.Println("An instance of the application is already running!",
"Provide the 'status' parameter to see stats.")
}
}
想要获取您的 运行ning 应用程序状态的进程只需发出 HTTP GET
请求(例如 linux 中的 wget)即可获取状态。上述应用程序将以下状态文本作为响应:
jobs waiting in queue : 120
processing jobs : 3414
jobs done : 300
重要提示:
我在地址 "localhost:8081"
上启动了网络服务器,这意味着统计信息只能从本地主机(同一台计算机)获得。如果您的应用程序已经使用网络服务器,您可以使用它,但请注意,如果可以从 "outside" 访问它,那么您的统计信息也将是。如果这是不需要的,您必须检查请求(客户端)是否来自本地主机,如果不是,您可以拒绝服务该请求。
没有外部进程
查询状态的"external process"甚至不必是外部的,您可以在应用程序本身实现它。
使用你的例子:启动时应用程序可以检查status
命令行参数是否存在,如果存在,它不会继续正常的启动过程,而是执行HTTP GET
来获取应用程序的另一个 运行ning 实例的状态,将其打印到控制台并在之后立即退出。
以下是您的操作方法。修改后的main()
函数:
func main() {
if len(os.Args) > 1 && os.Args[1] == "status" {
getStatus()
return
}
http.HandleFunc("/", ServeStats)
err := http.ListenAndServe("localhost:8081", nil)
if err != nil {
fmt.Println("An instance of the application is already running!",
"Provide the 'status' parameter to see stats.")
}
}
并执行getStatus()
:
func getStatus() {
resp, err := http.Get("http://localhost:8081/")
if err != nil {
fmt.Println("No running instance found!")
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Running instance found but failed to get status!")
return
}
fmt.Println("Status of the running instance:")
fmt.Println(string(body))
}
如果您不提供任何参数(或不提供 "status"
参数),应用程序会尝试正常启动。
如果您提供参数 "status"
,它会尝试从 运行ning 实例获取状态。如果成功,打印接收到的状态。如果不是,打印没有找到 运行ning 实例。无论哪种方式,运行 在那之后终止。
我想获取 运行 申请的申请状态。例如:
# start my app
./my_app
# require status
./my_app status
# it prints information about the application
jobs waiting in queue : 120
processing jobs : 3414
jobs done : 300
number of bad request received : 120
[...]
目前我认为只有一种选择可以实现此结果:使用外部进程。
外部进程"speak"与主应用程序通过一个文件(它touch
一个新文件,所以主应用程序"knows"它必须准备状态报告),然后当状态报告准备好后,它发送回外部进程(通过文件),最后这个将状态打印到 cli。
但我个人觉得这个解决方案不太优雅。
您还有其他想法来实现这一目标吗?该应用程序是用 Golang 编写的,Go 中是否有任何技巧可以做到这一点?
文件系统不是为应用程序提供输入的唯一方式,还有许多其他方式,例如将数据发送到其标准输入,应用程序可以在端口上侦听传入连接或使用任何其他外围设备(如麦克风、传感器等)。
由于 Go 有一个内置的网络服务器,利用它可能很方便:Go 应用程序可以启动网络服务器(如果它还没有使用它),并在端口上侦听传入连接,当请求到来时,只需将状态作为简单文本或 HTML 格式发回。
这是一个例子:
package main
import (
"fmt"
"net/http"
)
var (
waiting = 120
processing = 3414
done = 300
)
func ServeStats(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%-22s : %d\n", "jobs waiting in queue", waiting)
fmt.Fprintf(w, "%-22s : %d\n", "processing jobs", processing)
fmt.Fprintf(w, "%-22s : %d\n", "jobs done", done)
}
func main() {
http.HandleFunc("/", ServeStats)
err := http.ListenAndServe("localhost:8081", nil)
if err != nil {
fmt.Println("An instance of the application is already running!",
"Provide the 'status' parameter to see stats.")
}
}
想要获取您的 运行ning 应用程序状态的进程只需发出 HTTP GET
请求(例如 linux 中的 wget)即可获取状态。上述应用程序将以下状态文本作为响应:
jobs waiting in queue : 120
processing jobs : 3414
jobs done : 300
重要提示:
我在地址 "localhost:8081"
上启动了网络服务器,这意味着统计信息只能从本地主机(同一台计算机)获得。如果您的应用程序已经使用网络服务器,您可以使用它,但请注意,如果可以从 "outside" 访问它,那么您的统计信息也将是。如果这是不需要的,您必须检查请求(客户端)是否来自本地主机,如果不是,您可以拒绝服务该请求。
没有外部进程
查询状态的"external process"甚至不必是外部的,您可以在应用程序本身实现它。
使用你的例子:启动时应用程序可以检查status
命令行参数是否存在,如果存在,它不会继续正常的启动过程,而是执行HTTP GET
来获取应用程序的另一个 运行ning 实例的状态,将其打印到控制台并在之后立即退出。
以下是您的操作方法。修改后的main()
函数:
func main() {
if len(os.Args) > 1 && os.Args[1] == "status" {
getStatus()
return
}
http.HandleFunc("/", ServeStats)
err := http.ListenAndServe("localhost:8081", nil)
if err != nil {
fmt.Println("An instance of the application is already running!",
"Provide the 'status' parameter to see stats.")
}
}
并执行getStatus()
:
func getStatus() {
resp, err := http.Get("http://localhost:8081/")
if err != nil {
fmt.Println("No running instance found!")
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Running instance found but failed to get status!")
return
}
fmt.Println("Status of the running instance:")
fmt.Println(string(body))
}
如果您不提供任何参数(或不提供 "status"
参数),应用程序会尝试正常启动。
如果您提供参数 "status"
,它会尝试从 运行ning 实例获取状态。如果成功,打印接收到的状态。如果不是,打印没有找到 运行ning 实例。无论哪种方式,运行 在那之后终止。