为了账号安全,请及时绑定邮箱和手机立即绑定

获取正在运行的应用程序的自定义状态

获取正在运行的应用程序的自定义状态

Go
交互式爱情 2021-09-27 16:11:02
我想获取正在运行的应用程序的应用程序状态。例如:# start my app./my_app# require status./my_app status# it prints information about the applicationjobs waiting in queue : 120processing jobs       : 3414jobs done             : 300number of bad request received : 120[...]目前我看到只有一种选择可以实现这一结果:使用外部流程。外部进程通过一个文件(它touch是一个新文件,所以主应用程序“知道”它必须准备状态报告)与主应用程序“对话” ,然后当状态报告准备好时,它发送回外部进程(通过文件),最后这个将状态打印到 cli。但我个人觉得这个解决方案不是那么优雅。你有其他想法来实现这一目标吗?该应用程序是用 Golang 编写的,Go 中有没有什么技巧可以做到这一点?
查看完整描述

1 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

文件系统不是为应用程序提供输入的唯一方式,还有许多其他方式,例如将数据发送到其标准输入,应用程序可以侦听端口以获取传入连接或使用任何其他外围设备(如麦克风、传感器等) .)


由于 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.")

    }

}

想要获取正在运行的应用程序状态的进程只需发出HTTP GET请求(例如 linux 中的 wget)即可获取状态。上述应用程序提供以下状态文本作为响应:


jobs waiting in queue  : 120

processing jobs        : 3414

jobs done              : 300

重要的提示:


我在地址上启动了网络服务器,"localhost:8081"这意味着统计信息只能从本地主机(同一台计算机)获得。如果您的应用程序已经使用网络服务器,您可以使用它,但请注意,如果它可以从“外部”访问,那么您的统计信息也将如此。如果这是不需要的,您必须检查请求(客户端)是否来自本地主机,如果不是,您可以拒绝为请求提供服务。


没有外部流程

查询状态的“外部进程”甚至不必是external,您可以在应用程序本身中实现它。


使用您的示例:启动时的应用程序可以检查status命令行参数是否存在,如果存在,它将不会继续正常的启动过程,而是执行HTTP GET以获取应用程序的另一个正在运行的实例的状态,将其打印到控制台并立即退出。


这是您如何做到的。修改后的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",它会尝试从正在运行的实例中获取状态。如果成功,则打印接收到的状态。如果没有,则打印没有找到正在运行的实例。无论哪种方式,运行都会在此之后终止。


查看完整回答
反对 回复 2021-09-27
  • 1 回答
  • 0 关注
  • 235 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信