當前位置:首頁 » 編程軟體 » nodeexporter編譯

nodeexporter編譯

發布時間: 2022-09-06 12:30:53

❶ 如何用sublimeText3編寫less並用Nodejs自動編譯成css

1、安裝Sublime 插件
(1)安裝LESS插件:
因為Sublime不支持Less語法高亮,
所以,先安裝這個插件,
方法1: ctrl+shift+p>install Package>輸入less按Enter
方法2:直接下載後 解壓文件 放到插件文件夾下(首選項-瀏覽插件 打開文件夾)
下載地址:https://github.com/danro/LESS-sublime
(2)安裝LESS2CSS插件:
less2css的讀音 其實就是less to css
這個插件的作用是
當保存less文件的時候自動生成同名的css文件;
當保存less文件的時候提示編譯錯誤信息;
批量編譯項目目錄下的所有less文件為css文件。
安裝:
方法1:ctrl+shift+p>install Package>輸入less2css按Enter
方法2:直接下載:https://github.com/timdouglas/sublime-less2css
解壓文件 放到插件文件夾下
但是我們還要讓sublime支持less並自動編譯,所以還需以下步驟:
2、安裝Node.js
首先先配置一下環境,
less需要nodejs支持,
所以我們先要安裝一下nodejs
到nodejs官網下載就可以了:https://nodejs.org/en/
3、安裝less
運行-cmd:
輸入命令行:
npm install less -g
-g 代表著全局安裝less
之後在 Sublime 裡面建less文件時,會有一個錯誤
LESS: Unable to interpret argument clean-css
這是因為還需要一個插件
less-plugin-clean-css插件的安裝
命令行為:
npm install less-plugin-clean-css -g
接著重啟一下sublime,就搞定啦!

❷ 如何編寫 Node.js 擴展

一、編寫Node.js原生擴展

Node.js是一個強大的平台,理想狀態下一切都都可以用javascript寫成。然而,你可能還會用到許多遺留的庫和系統,這樣的話使用c++編寫Node.JS擴展會是一個不錯的注意。

以下所有例子的源代碼可在node擴展示例中找到 。

編寫Node.js C + +擴展很大程度上就像是寫V8的擴展; Node.js增加了一些介面,但大部分時間你都是在使原始的V8數據類型和方法,為了理解以下的代碼,你必須首先閱讀V8引擎嵌入指南。

Javascript版本的Hello World

在講解C++版本的例子之前,先讓我們來看看在Node.js中用Javascript編寫的等價模塊是什麼樣子。這是一個最簡單的Hello World,也不是通過HTTP,但它展示了node模塊的結構,而其介面也和大多數C++擴展要提供的介面差不多:

HelloWorldJs = function() {

this.m_count = 0;

};

HelloWorldJs.prototype.hello = function()

{

this.m_count++;

return 「Hello World」;

};

exports.HelloWorldJs = HelloWorldJs;

正如你所看到的,它使用prototype為HelloWorldJs類創建了一個新的方法。請注意,上述代碼通過將HelloWorldJS添加到exports變數來暴露構造函數。

要在其他地方使用該模塊,請使用如下代碼:

var helloworld = require(『helloworld_js』);

var hi = new helloworld.HelloWorldJs();

console.log(hi.hello()); // prints 「Hello World」 to stdout

C++版本的Hello World

要開始編寫C++擴展,首先要能夠編譯Node.js(請注意,我們使用的是Node.js 2.0版本)。本文所講內容應該兼容所有未來的0.2.x版本。一旦編譯安裝完node,編譯模塊就不在需要額外的東西了。

完整的源代碼可以在這里找到 。在使用Node.js或V8之前,我們需要包括相關的頭文件:

#include <v8.h>

#include <node.h>

using namespace node;

using namespace v8;

在本例子中我直接使用了V8和node的命名空間,使代碼更易於閱讀。雖然這種用法和谷歌的自己的C++編程風格指南相悖,但由於你需要不停的使用V8定義的類型,所以目前為止的大多數node的擴展仍然使用了V8的命名空間。

接下來,聲明HelloWorld類。它繼承自node::ObjectWrap類 ,這個類提供了幾個如引用計數、在V8內部傳遞contex等的實用功能。一般來說,所有對象應該繼承ObjectWrap:

class HelloWorld: ObjectWrap

{

private:

int m_count;

public:

聲明類之後,我們定義了一個靜態成員函數,用來初始化對象並將其導入Node.js提供的target對象中。設個函數基本上是告訴Node.js和V8你的類是如何創建的,和它將包含什麼方法:

static Persistent<FunctionTemplate> s_ct;

static void Init(Handle<Object> target)

{

HandleScope scope;

Local<FunctionTemplate> t = FunctionTemplate::New(New);

s_ct = Persistent<FunctionTemplate>::New(t);

s_ct->InstanceTemplate()->SetInternalFieldCount(1);

s_ct->SetClassName(String::NewSymbol(「HelloWorld」));

NODE_SET_PROTOTYPE_METHOD(s_ct, 「hello」, Hello);

target->Set(String::NewSymbol(「HelloWorld」),

s_ct->GetFunction());

}

在上面這個函數中target參數將是模塊對象,即你的擴展將要載入的地方。(譯著:這個函數將你的對象及其方法連接到
這個模塊對象,以便外界可以訪問)首先我們為New方法創建一個FunctionTemplate,將於稍後解釋。我們還為該對象添加一個內部欄位,並命
名為HelloWorld。然後使用NODE_SET_PROTOTYPE_METHOD宏將hello方法綁定到該對象。最後,一旦我們建立好這個函數模板後,將他分配給target對象的HelloWorld屬性,將類暴露給用戶。

接下來的部分是一個標準的C++構造函數:

HelloWorld() :

m_count(0)

{

}

~HelloWorld()

{

}

接下來,在::New 方法中V8引擎將調用這個簡單的C++構造函數:

static Handle<Value> New(const Arguments& args)

{

HandleScope scope;

HelloWorld* hw = new HelloWorld();

hw->Wrap(args.This());

return args.This();

}

此段代碼相當於上面Javascript代碼中使用的構造函數。它調用new HelloWorld
創造了一個普通的C++對象,然後調用從ObjectWrap繼承的Wrap方法,
它將一個C++HelloWorld類的引用保存到args.This()的值中。在包裝完成後返回args.This(),整個函數的行為和
javascript中的new運算符類似,返回this指向的對象。

現在我們已經建立了對象,下面介紹在Init函數中被綁定到hello的函數:

static Handle<Value> Hello(const Arguments& args)

{

HandleScope scope;

HelloWorld* hw = ObjectWrap::Unwrap<HelloWorld>(args.This());

hw->m_count++;

Local<String> result = String::New(「Hello World」);

return scope.Close(result);

}

函數中首先使用ObjectWrap模板的方法提取出指向HelloWorld類的指針,然後和javascript版本的HelloWorld一樣遞增計數器。我們新建一個內容為「HelloWorld」的v8字元串對象,然後在關閉本地作用域的時候返回這個字元串。

上面的代碼實際上只是針對v8的介面,最終我們還需要讓Node.js知道如何動態載入我們的代碼。為了使Node.js的擴展可以在執行時從動態鏈接庫載入,需要有一個dlsym函數可以識別的符號,所以執行編寫如下代碼:

extern 「C」 {

static void init (Handle<Object> target)

{

HelloWorld::Init(target);

}

NODE_MODULE(helloworld, init);

}

由於c++的符號命名規則,我們使用extern
C,以便該符號可以被dysym識別。init方法是Node.js載入模塊後第一個調用的函數,如果你有多個類型,請全部在這里初始化。
NODE_MODULE宏用來填充一個用於存儲模塊信息的結構體,存儲的信息如模塊使用的API版本。這些信息可以用來防止未來因API不兼容導致的崩
潰。

到此,我們已經完成了一個可用的C++ NodeJS擴展。

Node.js也提供了一個用於構建模塊的簡單工具:
node-waf首先編寫一個包含擴展編譯方法的wscript文件,然後執行node-waf configure &&
node-waf build完成模塊的編譯和鏈接工作。對於這個helloworld的例子來說,wscript內容如下:

def set_options(opt):

opt.tool_options(「compiler_cxx」)

def configure(conf):

conf.check_tool(「compiler_cxx」)

conf.check_tool(「node_addon」)

def build(bld):

obj = bld.new_task_gen(「cxx」, 「shlib」, 「node_addon」)

obj.cxxflags = [「-g」, 「-D_FILE_OFFSET_BITS=64」, 「-D_LARGEFILE_SOURCE」, 「-Wall」]

obj.target = 「helloworld」

obj.source = 「helloworld.cc」

非同步IO的HelloWorld

對於實際的應用來說,HelloWorld的示例太過簡單了一些,Node.js主要的優勢是提供非同步IO。
Node.js內部通過libeio將會產生阻塞的操作全都放入線程池中執行。如果需要和遺留的c庫交互,通常需要使用非同步IO來為javascript
代碼提供回調介面。

通常的模式是提供一個回調,在非同步操作完成時被調用——你可以在整個Node.js的API中看到這種模式。
Node.js的filesystem模塊提供了一個很好的例子,其中大多數的函數都在操作完成後通過調用回調函數來傳遞數據。和許多傳統的GUI框架一
樣,Node.js只在主線程中執行JavaScript,因此主線程以外的任何操作都不應該直接和V8或Javascript交互。

同樣helloworld_eio.cc源代碼在GitHub上。我只強調和原來HelloWorld之間的差異,其中大部分代碼保持不變,變化集中在Hello方法中:

static Handle<Value> Hello(const Arguments& args)

{

HandleScope scope;

REQ_FUN_ARG(0, cb);

HelloWorldEio* hw = ObjectWrap::Unwrap<HelloWorldEio>(args.This());

在Hello函數的入口處 ,我們使用宏從參數列表的第一個位置獲取回調函數,在下一節中將詳細介紹。然後,我們使用相同的Unwarp方法提取指向類對象的指針。

hello_baton_t *baton = new hello_baton_t();

baton->hw = hw;

baton->increment_by = 2;

baton->sleep_for = 1;

baton->cb = Persistent<Function>::New(cb);

這里我們創建一個baton結構,並將各種參數保存在裡面。請注意,我們為回調函數創建了一個永久引用,因為我們想要在超出當前函數作用域的地方使用它。如果不這么做,在本函數結束後將無法再調用回調函數。

hw->Ref();

eio_custom(EIO_Hello, EIO_PRI_DEFAULT, EIO_AfterHello, baton);

ev_ref(EV_DEFAULT_UC);

return Undefined();

}

如下代碼是真正的重點。首先,我們增加HelloWorld對象的引用計數,這樣在其他線程執行的時候他就不會被回收。
函數eio_custom接受兩個函數指針作為參數。EIO_Hello函數將在線程池中執行,然後EIO_AfterHello函數將回到在「主線程」
中執行。我們的baton結構也被傳遞進各函數,這些函數可以使用baton結構中的數據完成相關的操作。同時,我們也增加event
loop的引用。這很重要,因為如果event
loop無事可做,Node.js就會退出。最終,函數返回Undefined,因為真正的工作將在其他線程中完成。

static int EIO_Hello(eio_req *req)

{

hello_baton_t *baton = static_cast<hello_baton_t *>(req->data);

sleep(baton->sleep_for);

baton->hw->m_count += baton->increment_by;

return 0;

}

這個回調函數將在libeio管理的線程中執行。首先,解析出baton結構,這樣可以訪問之前設置的各種參數。然後
sheep
baton->sleep_for秒,這么做是安全的,因為這個函數運行在獨立的線程中並不會阻塞主線程中javascript的執行。然後我們的
增計數器,在實際的系統中,這些操作通常需要使用Lock/Mutex進行同步。

當上述方法返回後,libeio將會通知主線程它需要在主線成上執行代碼,此時EIO_AfterHello將會被調用。

static int EIO_AfterHello(eio_req *req)

{

HandleScope scope;

hello_baton_t *baton = static_cast<hello_baton_t *>(req->data);

ev_unref(EV_DEFAULT_UC);

baton->hw->Unref();

進度此函數時,我們提取出baton結構,刪除事件循環的引用,並減少HelloWorld對象的引用。

Local<Value> argv[1];

argv[0] = String::New(「Hello World」);

TryCatch try_catch;

baton->cb->Call(Context::GetCurrent()->Global(), 1, argv);

if (try_catch.HasCaught()) {

FatalException(try_catch);

}

新建要傳遞給回調函數的字元串參數,並放入字元串數組中。然後我們調用回調傳遞一個參數,並檢測可能拋出的異常。

baton->cb.Dispose();

delete baton;

return 0;

}

在執行過回調之後,應該銷毀持久引用,然後刪除之前創建的baton結構。

最後,你可以使用如下形式在Javascript中使用該模塊:

var helloeio = require(『./helloworld_eio』);

hi = new helloeio.HelloWorldEio();

hi.hello(function(data){

console.log(data);

});

參數傳遞與解析

除了HelloWorld之外,你還需要理解最後一個問題:參數的處理。在helloWorld EIO例子中,我們使用一個REQ_FUN_ARG宏,然我們看看這個宏到底都做些什麼。

#define REQ_FUN_ARG(I, VAR) \

if (args.Length() <= (I) || !args[I]->IsFunction()) \

return ThrowException(Exception::TypeError( \

String::New(「Argument 」 #I 」 must be a function」))); \

Local<Function> VAR = Local<Function>::Cast(args[I]);

就像Javascript中的argument變數,v8使用數組傳遞所有的參數。由於沒有嚴格的類型限制,所以傳遞給函數的參數數目可能和期待的不同。為了對用戶友好,使用如下的宏檢測一下參數數組的長度並判斷參數是否是正確的類型。如果傳遞了錯誤的參數類型,該宏將會拋出TypeError異常。為簡化參數的解析,目前為止大多數的Node.js擴展都有一些本地作用域內的宏,用於特定類型參數的檢測。

二、揭秘node.js事件

要使用NodeJS,你需要知道一個重要的東西:事件(events)。Node中有很多對象都可以觸發事件,Node
的文檔中有很多示例。但文檔也許並不能清晰的講解如何編寫自定義事件以及監聽函數。對於一些簡單的程序你可以不使用自定義事件,但這樣很難應對復雜的應
用。那麼如何編寫自定義事件?首先需要了解的是在node.js中的』events』模塊。

快速概覽

要訪問此模塊,只需使用如下語句:

require(『events』)
requires(『events』).EventEmitter

特別說明,node中所有能觸發事件的對象基本上都是後者的實例。讓我們創建一個簡單的演示程序Dummy:

mmy.js

view plain to clipboardprint?

// basic imports
var events = require(『events』);

// for us to do a require later
mole.exports = Dummy;

function Dummy() {
events.EventEmitter.call(this);
}
10.

11. // inherit events.EventEmitter

12. Dummy.super_ = events.EventEmitter;

13. Dummy.prototype = Object.create(events.EventEmitter.prototype, {

14. constructor: {
15. value: Dummy,
16. enumerable: false
17. }

18. });

// basic imports

var events = require(『events』);

// for us to do a require later

mole.exports = Dummy;

function Dummy() {

events.EventEmitter.call(this);

}

// inherit events.EventEmitter

Dummy.super_ = events.EventEmitter;

Dummy.prototype = Object.create(events.EventEmitter.prototype, {

constructor: {

value: Dummy,

enumerable: false

}

});

上述代碼中重點展示如何使用EventEmitter擴充對象,並從中繼承所有的原型對象,方法…等等。

現在,我們假設Dummy有一個cooking()的方法,一旦把食物做熟之後它會觸發』cooked』事件,並調用一個名為』eat』的回調函數。

mmy-cooking.js

view plain to clipboardprint?

Dummy.prototype.cooking = function(chicken) {
var self = this;
self.chicken = chicken;
self.cook = cook(); // assume mmy function that』ll do the cooking
self.cook(chicken, function(cooked_chicken) {
self.chicken = cooked_chicken;
self.emit(『cooked』, self.chicken);
});

10. return self;

11. }

Dummy.prototype.cooking = function(chicken) {

var self = this;

self.chicken = chicken;

self.cook = cook(); // assume mmy function that』ll do the cooking

self.cook(chicken, function(cooked_chicken) {

self.chicken = cooked_chicken;

self.emit(『cooked』, self.chicken);

});

return self;

}

❸ 普羅米修斯怎麼監控主機oom detect

一、監控主機(其他主機一樣)
1、被監控伺服器需要安裝node_exporter
(1)下載node_exporter-1.1.2.linux-amd64.tar.gz,解壓到/usr/local目錄下並重命名node_exporter
(2)啟動 node_exporter
2、添加grafana伺服器監控節點信息並重啟,重啟prometheus
3、查看是否添加成功打開瀏覽器輸入:http://IP:9090/
4、訪問grafana,添加圖像界面瀏覽器訪問IP:3000埠
1、添加數據源5、導入模板,模板可以到官網下載,docker 主機監控模板:193Liunx主機監控模板:9276
二、監控docker容器1、添加監控節點同理
2、在被監控伺服器部署cadvisor容器
3、驗證瀏覽器訪問http://IP:8082/
4、添加數據源同理
5、導入模板同理。

❹ vue: WebStorm設置快速編譯運行的方法

WebSorm是一款優秀的前端開發工具,而Vue項目可以使用Node進行編譯運行,平常我們可以通過命令行部署項目進行調試。
本文介紹設置Webstorm進行快速部署Vue項目。
第一步
點擊啟動快捷按鈕旁邊的向下小箭頭,在列表中選擇Edit選項:
第二步
打開啟動設置頁面後,點擊左上角的加號添加新的運行方式:
第三步
在彈出的選擇框中,選擇node.js啟動模式:
第四步
在新打開的設置頁面中,在紅色圈中的地方設置如圖路徑的文件:
至此設置成功,直接點啟動按鈕就可以部署項目。
以上這篇vue:
WebStorm設置快速編譯運行的方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
您可能感興趣的文章:webstorm添加*.vue文件支持webstorm添加vue.js支持的方法教程webstorm中vue語法的支持詳解webstorm和.vue中es6語法報錯的解決方法詳解Webstorm
新建.vue文件支持高亮vue語法和es6語法

❺ node_exporter修改啟動埠

https://blog.csdn.net/weixin_44723434/article/details/89237202

❻ 運行在服務端的Node.js代碼需要編譯嗎

首先實現一個處理靜態資源的函數,其實就是對本地文件的讀取操作,這個方法已滿足了上面說的靜態資源的處理。
//處理靜態資源
function staticResHandler(localPath, ext, response) {
fs.readFile(localPath, "binary", function (error, file) {
if (error) {
response.writeHead(500, { "Content-Type": "text/plain" });
response.end("Server Error:" + error);
} else {
response.writeHead(200, { "Content-Type": getContentTypeByExt(ext) });
response.end(file, "binary");
}
});
}

❼ 如何用命令行編譯nodejs文件

在window平台,.js文件默認是cscript運行的。
你可以用node 空格 js文件名的方式用nodejs運行js文件,不能直接運行。

❽ 2020-08-25

Prometheus 實現郵件告警(Prometheus+Alertmanager+QQ郵箱或者網易163郵箱,目前測試過這兩種郵箱都可以發送告警郵件)

Prometheus實現郵件告警原理如下:

Prometheus官方有一個附帶的中間件:alertmanager,通過設置rules規則和路由轉發可以實現郵件告警,前提是你需要有一個可以發送郵件的郵件服務端(可以自建或者使用互聯網公司提供的免費郵箱)

告警原理圖

Prometheus完整架構圖

我之前得出的錯誤結論如下:

推薦直接在虛擬機操作系統上直接安裝Prometheus和Alertmanager,不推薦其中任何一方在容器中運行,因為測試過在容器中運行Prometheus和alertmanager,結果出現如下錯誤情況

第一種情況是:我的node-exporter掉線跌機了(手動關機,模擬突然掉線跌機),Prometheus卻提示節點依然在線?有時候卻能夠正常顯示節點掉線跌機,生成告警發送郵件

第二種情況是:我的node-exporter掉線跌機了(手動關機,模擬突然掉線跌機),Prometheus提示節點掉線,告警生成,但是沒有發送郵件,我手動恢復node-exporter後,告警解除,郵件能正常發送郵件提示告警已經解除。。。。

第三種情況是:我的node-exporter掉線跌機了(手動關機,模擬突然掉線跌機),Prometheus提示節點掉線,告警生成,正常成功發送郵件,我手動恢復node-exporter後,告警解除,郵件沒有發送出來。。。。

以上三種情況之前經常出現,當時第一步以為是自己設置的scrape_interval不合理導致的,結果調試幾次,問題沒有解決,第二步以為是自己的伺服器時間沒有做到精確同步,然後我去設置和阿里雲的ntp伺服器同步,結果問題依然沒有解決,第三步,換個方向,把alertmanager遷移到虛擬機操作系統上安裝運行,問題解決!

北京時間是GMT+8小時,有些同志的時間可能是UTC的,但是如果是在要求不太十分精確的情況下,UTC時間是剛剛好等於GMT時間

為了避免時區的混亂,prometheus所有的組件內部都強制使用Unix時間,對外展示使用GMT時間。

要改時區有兩個辦法

1 .修改源碼,重新編譯。

2. 使用 docker 運行 Prometheus,掛載本地時區文件

docker run --restart always -e TZ=Asia/Shanghai --hostname prometheus --name prometheus-server -d -p 9090:9090 -v /data/prometheus/server/data:/prometheus -v /data/prometheus/server/conf/prometheus.yml:/etc/prometheus/prometheus.yml -u root prom/prometheus:v2.5.0

正文開始

安裝alertmanager

容器安裝方式:

docker run -d --name alertmanager -p 9093:9093 -v /usr/local/Prometheus/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml prom/alertmanager:latest

先在宿主機/usr/local/Prometheus下創建一個文件夾alertmanager,然後在文件夾里創建alertmanager.yml配置文件,待會才能映射到alertmanager容器里的/etc/alertmanager目錄下

global:全局配置

   resolve_timeout: 問題解決的超時時間

   smtp_from: 發送告警郵件的郵箱賬號

   smtp_smarthost: 郵箱 SMTP 服務地址,這里是以QQ郵箱為例,也可以用網易163郵箱,這個和我之前設置zabbix郵件告警時的配置一樣

   smtp_auth_username: 如果沒有設置郵箱別名,那就是賬戶名

   smtp_auth_password:  郵箱的授權碼,不是 賬戶密碼,你可以在QQ郵箱或者網易163郵箱網頁端設置,開啟 POP3/SMTP 服務時會提示,和配置zabbix郵件告警的時候幾乎一樣

   smtp_require_tls: 是否使用 tls,根據環境不同,來選擇開啟和關閉。如果提示報錯 email.loginAuth failed: 530 Must issue a STARTTLS command first,那麼就需要設置為 true。著重說明一下,如果開啟了 tls,提示報錯 starttls failed: x509: certificate signed by unknown authority,需要在 email_configs 下配置 insecure_skip_verify: true 來跳過 tls 驗證。

templates: 告警模板目錄,可以不編寫模板,有默認模板

    Subject: '{{ template "email.default.subject" . }}'

    html: '{{ template "email.default.html" . }}'

route:報警的分發設置

    group_by:分組

    group_wait: 分組等待時間

    group_interval: 5m 每組時間間隔

    repeat_interval: 10m 重復間隔

    receiver: 接收方式,請注意!這里的名字要對應下面receivers中的任何一個名字,不然會報錯,這里其實就是選擇方式,有郵箱,企業微信,wehook,victorops等等

receivers:接受方式匯總,即告警方式匯總

例子:

receivers:

- name:'default-receiver' 

email_configs:

- to:'[email protected]'    

  html: '{{ template "alert.html" . }}'    

  headers: { Subject: "[WARN] 報警郵件test"}

inhibit_rules:   抑制規則

當存在與另一組匹配的警報(源)時,抑制規則將禁用與一組匹配的警報(目標)。

包括源匹配和目標匹配

alertmanager官方是這樣說的

Inhibition

Inhibition is a concept of suppressing notifications for certain alerts if certain other alerts are already firing.

Example:  An alert is firing that informs that an entire cluster is not reachable. Alertmanager can be configured to mute all other alerts concerning this cluster if that particular alert is firing. This prevents notifications for hundreds or thousands of firing alerts that are unrelated to the actual issue.

Inhibitions are configured through the Alertmanager's configuration file.

當存在與另一組匹配器匹配的警報(源)時,禁止規則會使與一組匹配器匹配的警報(目標)靜音。目標警報和源警報的equal列表中的標簽名稱都必須具有相同的標簽值。

在語義上,缺少標簽和帶有空值的標簽是同一件事。因此,如果equal源警報和目標警報都缺少列出的所有標簽名稱,則將應用禁止規則。

為了防止警報禁止自身,與規則的目標和源端 都 匹配的警報不能被警報(包括其本身)為真來禁止。但是,我們建議選擇目標匹配器和源匹配器,以使警報永遠不會同時匹配雙方。這很容易進行推理,並且不會觸發此特殊情況。

接著是規則rules

不解釋了,自己研究官方文檔

alertmanager的非容器安裝方式是

 wget https://github.com/prometheus/alertmanager/releases/download/v0.20.0/alertmanager-0.20.0.linux-amd64.tar.gz

tar xf alertmanager-0.20.0.linux-amd64.tar.gz

mv alertmanager-0.20.0.linux-amd64 /usr/local/alertmanager

vim /usr/lib/systemd/system/alertmanager.service

[Unit]

Description=alertmanager

Documentation=https://github.com/prometheus/alertmanager

After=network.target

[Service]

Type=simple

User=root

ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml

Restart=on-failure

[Install]

WantedBy=multi-user.target

Alertmanager 安裝目錄下默認有 alertmanager.yml 配置文件,可以創建新的配置文件,在啟動時指定即可。

其餘方式和上面一樣

接著是Prometheus,我之前的博客里有寫了容器安裝和非容器安裝的方法,自己去翻閱

然後是在prometheus.yml里修改相關配置

首先去掉alertmanager的注釋,改成IP加你設置的埠號,默認是9093

接著在rule_files: 下面寫下規則文件的絕對路徑,可以是具體文件名,也可以是*,也可以分幾級文件,*默認是全部匹配

接著是被監控項的設置,這里設置完成可以在Prometheus網頁里的targets里看得到

請注意,這里設置的參數名字要和rule規則中設置的參數名字一模一樣,否則你的prometheus服務會無法啟動,然後報錯

如果不在特定的job下設置scrape_interval(優先順序高於全局),則默認採用gobal下的scrape_interval

最後模擬節點掉線,手動關閉node-exporter或者Cadvisor

docker stop node-exporter 或者容器ID

docker stop cadvisor 或者容器ID

或者把up{{job='prometheus'}} == 1 設置成1,反向設置,不用關掉服務,就可以看看告警成不成功

說明一下 Prometheus Alert 告警狀態有三種狀態:Inactive、Pending、Firing。

Inactive:非活動狀態,表示正在監控,但是還未有任何警報觸發。

Pending:表示這個警報必須被觸發。由於警報可以被分組、壓抑/抑制或靜默/靜音,所以等待驗證,一旦所有的驗證都通過,則將轉到 Firing 狀態。

Firing:將警報發送到 AlertManager,它將按照配置將警報的發送給所有接收者。一旦警報解除,則將狀態轉到 Inactive,如此循環。

沒有配置告警模板時的默認告警格式是這樣的

節點恢復後郵件告知是這樣的

寫了模板後是這樣的

還要重新映射模板文件夾路徑到alertmanager容器里的相對路徑,然後重啟alertmanager,當然,如果目錄下沒有模板文件,則不顯示

告警模板

在alertmanager.yml中修改相關設置

重啟alertmanager

docker restart alertmanager

最終效果不是很好

❾ Prometheus的四大指標類型

Prometheus有4大指標類型(Metrics Type),分別是Counter(計數器)、Gauge(儀表盤)、Histogram(直方圖)和Summary(摘要)。

這是在Prometheus客戶端(目前主要有Go、Java、Python、Ruby等語言版本)中提供的4種核心指標類型,但是Prometheus的服務端並不區分指標類型,而是簡單地把這些指標統一視為無類型的時間序列。

注意:

<font color=red>上面這句話應該這么理解,四個指標類型,實際上就是客戶端採集數據的四個維度,採集這四個維度的指標數據,但是最終匯總到服務端那裡,則是對這四個維度無感的,只是簡單的作為時間序列存儲起來。</font>

 計數器表示一種單調遞增的指標,除非發生重置的情況下下只增不減,其樣本值應該是不斷增大的。例如,可以使用Counter類型的指標來表示服務的請求數、已完成的任務數、錯誤發生的次數等。

 但是,計數器計算的總數對用戶來說大多沒有什麼用,大家千萬不要將計數器類型應用於樣本數據非單調遞增的指標上,比如當前運行的進程數量、當前登錄的用戶數量等應該使用儀表盤類型。

為了能夠更直觀地表示樣本數據的變化情況,往往需要計算樣本的增長速率,這時候通常使用PromQL的rate、topk、increase和irate等函數,如下所示:

如上所示,速率的輸出rate(v range-vector)也應該用儀表盤來承接結果。

在上面的案例中,如果有一個標簽是Device,那麼在統計每台機器每秒接受的HTTP請求數時,可以用如下的例子進行操作。

補充

 這背後與rate()的實現方式有關,rate()在設計上假定對應的指標是一個計數器,也就是只有<font color=red>incr(增加)和reset(歸零)</font>兩種行為。而執行了sum()或其他聚合操作之後,得到的就不再是一個計數器了。舉個例子,比如sum()的計算對象中有一個歸零了,那整體的和會下降,而不是歸零,這會影響rate()中判斷reset(歸零)的邏輯,從而導致錯誤的結果。

 increase(v range-vector)函數傳遞的參數是一個區間向量,increase函數獲取區間向量中的第一個和最後一個樣本並返回其增長量。下面的例子可以查詢Counter類型指標的增長速率,可以獲取http_requests_total在最近5分鍾內的平均樣本,其中300代表300秒。

 rate和increase函數計算的增長速率容易陷入<font color=red>長尾效應中</font>。比如在 某一個由於訪問量或者其他問題導致CPU佔用100%的情況中,通過計算在時間窗口內的平均增長速率是無法反映出該問題的

 為什麼監控和性能測試中,我們更關注p95/p99位?就是因為長尾效應。由於個別請求的響應時間需要1秒或者更久,<font color=red>傳統的響應時間的平均值就體現不出響應時間中的尖刺了</font>,去尖刺也是數據採集中一個很重要的工序,這就是所謂的長尾效應。p95/p99就是長尾效應的分割線,如表示99%的請求在XXX范圍內,或者是1%的請求在XXX范圍之外。99%是一個范圍,意思是99%的請求在某一延遲內,剩下的1%就在延遲之外了。只是正推與逆推而已,是一種概念的兩種不同描述。

 irate(v range-vector)是PromQL針對長尾效應專門提供的靈敏度更高的函數。irate同樣用於計算區間向量的增長速率,但是其反映出的是瞬時增長速率。irate函數是通過區間向量中最後兩個樣本數據來計算區間向量的增長速率的。這種方式可以避免在時間窗口范圍內的「長尾問題」,並且體現出更好的靈敏度。通過irate函數繪制的圖標能夠更好地反映樣本數據的瞬時變化狀態。irate的調用命令如下所示。

 irate函數相比於rate函數提供了更高的靈敏度,不過分析長期趨勢時或者在告警規則中,irate的這種靈敏度反而容易造成干擾。因此,在長期趨勢分析或者告警中更推薦使用rate函數。

 儀表盤類型代表一種<font color=red>樣本數據可以任意變化的指標,即可增可減</font>。它可以理解為狀態的快照,Gauge通常用於表示溫度或者內存使用率這種指標數據,也可以表示能隨時增加或減少的「總數」,例如當前並發請求的數量node_memory_MemFree(主機當前空閑的內容大小)、node_memory_MemAvailable(可用內存大小)等。在使用Gauge時,用戶往往希望使用它們<font color=red>求和、取平均值、最小值、最大值</font>等。

 以Prometheus經典的Node Exporter的指標node_filesystem_size_bytes為例,它可以報告從node_filesystem_size_bytes採集來的文件系統大小,包含device、fstype和mountpoint等標簽。如果想要對每一台機器上的總文件系統大小求和(sum),可以使用如下PromQL語句。

 without可以讓sum指令根據相同的標簽進行求和,但是忽略without涵蓋的標簽。如果在實際工作中需要忽略更多標簽,可以根據實際情況在without里傳遞更多指標。

補充

node_filesystem_size_bytes指標查詢

device, fstype, mountpoint都是他的標簽。

sum without(device, fstype, mountpoint)(node_filesystem_size_bytes)查詢

 如果要根據Node Exporter的指標node_filesystem_size_bytes計算每台機器上最大的文件安裝系統大小,只需要將上述案例中的sum函數改為max函數,如下所示。

 除了求和、求最大值等,利用Gauge的函數求最小值和平均值等原理是類似的。除了基本的操作外,Gauge經常結合PromQL的predict_linear和delta函數使用。

 predict_linear(v range-vector,t scalar)函數可以預測時間序列v在t秒後的值,就是使用線性回歸的方式,預測樣本數據的Gauge變化趨勢。例如,基於2小時的樣本數據,預測未來24小時內磁碟是否會滿,如下所示:

PromQL還有一個內置函數delta(),它可以獲取樣本在一段時間內的變化情況,也通常作用於Gauge。例如,計算磁碟空間在2小時內的差異,如下所示。

Histogram是一個對數據分布情況的圖形表示,由一系列高度不等的長條圖(bar)或線段表示,用於展示單個測度得知的分布。

[圖片上傳失敗...(image-3e55f2-1622153155462)]

上邊界、樣本值總和、樣本總數

例子

這三個查詢一起看

所有樣本值的總和,命名為<basename>_sum。

prometheus_http_request_ration_seconds_sum{handler="/targets",instance="192.168.16.134:9090",job="prometheus"}0.405075955 表示12 次http請求的總響應時間是0.405075955

命名為<basename>_count,其值和<basename>_bucket{le="+Inf"}相同(所有)。

prometheus_http_request_ration_seconds_count{handler="/targets",instance="192.168.16.134:9090",job="prometheus"}12 表示總共發生了12次請求

 sum函數和count函數相除,可以得到一些平均值,比如Prometheus一天內的平均壓縮時間,可由查詢結果除以instance標簽數量得到,如下所示。

 除了Prometheus內置的壓縮時間,prometheus_local_storage_series_chunks_persisted表示Prometheus中每個時序需要存儲的chunk數量,也可以用於計算待持久化的數據的分位數。

 Histogram可以用於觀察樣本數據的分布情況。Histogram的分位數計算需要通過histogram_quantile(φfloat,b instant-vector)函數進行計算,但是histogram_quantile計算所得並非精確值。其中,φ(0<φ<1)表示需要計算的分位數(這個值主要是通過prometheus_http_request_ration_seconds_bucket和prometheus_http_request_ration_seconds_sum兩個指標得到的,是一個近似值)。

例子如下。

 與Histogram類型類似,摘要用於表示一段時間內的數據采樣的結果(通常是請求持續時間或響應大小等),但它直接存儲了分位數(通過客戶端計算,然後展示出來),而非通過區間來計算(Histogram的分位數需要通過histogram_quantile(φfloat,b instant-vector)函數計算得到)。因此,對於分位數的計算,Summary在通過PromQL進行查詢時有更好的性能表現,而Histogram則會消耗更多的資源。反之,對於客戶端而言,Histogram消耗的資源更少。在選擇這兩種方式時,用戶應該根據自己的實際場景選擇。

Histogram是在服務端計算的,Summary是在客戶端計算的。

 安裝並啟動Prometheus後,在訪問 http://localhost:9090/metrics 時可以看到Prometheus自帶的一些Summary信息,這些信息和Histogram一樣在注釋中(#HELP和#TYPE)也會顯示,如下所示。

 在上述例子中,可以看到基於Go語言編寫的Prometheus的gc總次數是1907,耗時0.193642882s,其中中位數(quantile=0.5)計算的耗時為4.8366e-05s,代表1907次中50%的次數是小於4.8366e-05s的。

Summary類型的樣本也會提供3種指標,假設指標名稱為<basename>。

Summary和Histogram的異同

Summary的強大之處就是可以利用除法去計算時間的平均值。如果要從Histogram和Summary中計算最近5分鍾內的平均請求持續時間http_request_ration_seconds,可以用如下表達式進行。

count本質上是一個計數器,sum通常情況下也會像計數器那樣工作。但是<font color=red>Summary和Histogram可能觀察到負值,比如溫度(-20℃),這種情況下會導致觀察的總量下降,無法再使用rate函數</font>。

比如下面的例子就可以計算過去5分鍾內每次響應中返回的平均位元組數。

關於這個例子,我們需要注意幾點。

·因為http_response_size_bytes_count和http_response_size_bytes_sum是計數器類型,所以必須在計算前先使用rate等函數。

·因為Prometheus的API會有很多handler,所以可以使用without過濾掉handler的返回值。

·PromQL要先執行rate()再執行sum(),不能先執行sum()再執行rate()。

·在統計學上,尤其是計算平均值時,要先進行sum等求和運算再做除法。對一個平均值再求平均是不正確的,如下所示。

count的例子

案例一:計算所有的實例CPU核心數。

count by (instance) ( count by (instance,cpu) (node_cpu_seconds_total{mode=

"system"}) )

案例二:計算單個實例192.168.1.1的CPU核心數。

count by (instance) ( count by (instance,cpu) (node_cpu_seconds_total{mode="system",

instance="192.168.1.1"})

熱點內容
風險防控平台伺服器地址是什麼 發布:2025-03-20 11:59:04 瀏覽:231
什麼為有效wifi密碼 發布:2025-03-20 11:57:22 瀏覽:704
聯發科安卓哪個好 發布:2025-03-20 11:56:26 瀏覽:356
看門狗ce腳本 發布:2025-03-20 11:53:41 瀏覽:476
linuxcrypto 發布:2025-03-20 11:44:35 瀏覽:516
win7縮略圖緩存 發布:2025-03-20 11:31:30 瀏覽:69
c2c是什麼文件夾 發布:2025-03-20 11:30:45 瀏覽:687
交管12123的登錄密碼哪裡找 發布:2025-03-20 11:25:50 瀏覽:379
編程技術大牛 發布:2025-03-20 11:21:21 瀏覽:588
315演算法 發布:2025-03-20 11:15:35 瀏覽:213