前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊klog的Flush

聊聊klog的Flush

原创
作者头像
code4it
修改于 2020-12-29 02:07:53
修改于 2020-12-29 02:07:53
89002
代码可运行
举报
文章被收录于专栏:码匠的流水账码匠的流水账
运行总次数:2
代码可运行

本文主要研究一下klog的Flush

Flush

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Flush flushes all pending log I/O.
func Flush() {
    logging.lockAndFlushAll()
}

Flush方法执行的是logging.lockAndFlushAll()

init

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// init sets up the defaults and runs flushDaemon.
func init() {
    logging.stderrThreshold = errorLog // Default stderrThreshold is ERROR.
    logging.setVState(0, nil, false)
    logging.logDir = ""
    logging.logFile = ""
    logging.logFileMaxSizeMB = 1800
    logging.toStderr = true
    logging.alsoToStderr = false
    logging.skipHeaders = false
    logging.addDirHeader = false
    logging.skipLogHeaders = false
    logging.oneOutput = false
    go logging.flushDaemon()
}

klog的init方法异步协程执行logging.flushDaemon()

logging.flushDaemon()

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// flushDaemon periodically flushes the log file buffers.
func (l *loggingT) flushDaemon() {
    for range time.NewTicker(flushInterval).C {
        l.lockAndFlushAll()
    }
}

flushDaemon方法range新建ticker的channel,然后执行l.lockAndFlushAll()

lockAndFlushAll

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// lockAndFlushAll is like flushAll but locks l.mu first.
func (l *loggingT) lockAndFlushAll() {
    l.mu.Lock()
    l.flushAll()
    l.mu.Unlock()
}

lockAndFlushAll使用lock执行flushAll

flushAll

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const (
    infoLog severity = iota
    warningLog
    errorLog
    fatalLog
    numSeverity = 4
)

// flushAll flushes all the logs and attempts to "sync" their data to disk.
// l.mu is held.
func (l *loggingT) flushAll() {
    // Flush from fatal down, in case there's trouble flushing.
    for s := fatalLog; s >= infoLog; s-- {
        file := l.file[s]
        if file != nil {
            file.Flush() // ignore error
            file.Sync()  // ignore error
        }
    }
}

flushAll方法从fatalLog开始递减到infoLog级别挨个执行l.file[s]的Flush及Sync方法

flushSyncWriter

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// flushSyncWriter is the interface satisfied by logging destinations.
type flushSyncWriter interface {
    Flush() error
    Sync() error
    io.Writer
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

flushSyncWriter接口定义了Flush、Sync方法,内嵌了io.Writer接口

redirectBuffer

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// redirectBuffer is used to set an alternate destination for the logs
type redirectBuffer struct {
    w io.Writer
}

func (rb *redirectBuffer) Sync() error {
    return nil
}

func (rb *redirectBuffer) Flush() error {
    return nil
}

func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) {
    return rb.w.Write(bytes)
}

redirectBuffer内嵌了io.Writer,其Write方法通过io.Writer来写;其Sync及Flush方法都为空操作

syncBuffer

k8s.io/klog/v2@v2.4.0/klog.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// syncBuffer joins a bufio.Writer to its underlying file, providing access to the
// file's Sync method and providing a wrapper for the Write method that provides log
// file rotation. There are conflicting methods, so the file cannot be embedded.
// l.mu is held for all its methods.
type syncBuffer struct {
    logger *loggingT
    *bufio.Writer
    file     *os.File
    sev      severity
    nbytes   uint64 // The number of bytes written to this file
    maxbytes uint64 // The max number of bytes this syncBuffer.file can hold before cleaning up.
}

func (sb *syncBuffer) Sync() error {
    return sb.file.Sync()
}

func (sb *syncBuffer) Write(p []byte) (n int, err error) {
    if sb.nbytes+uint64(len(p)) >= sb.maxbytes {
        if err := sb.rotateFile(time.Now(), false); err != nil {
            sb.logger.exit(err)
        }
    }
    n, err = sb.Writer.Write(p)
    sb.nbytes += uint64(n)
    if err != nil {
        sb.logger.exit(err)
    }
    return
}

syncBuffer定义了logger、file、sev、nbytes、maxbytes属性,内嵌了*bufio.Writer;其Sync方法执行的是*os.File.Sync;其Flush方法执行的是*bufio.Writer.Flush

Flush

/usr/local/go/src/bufio/bufio.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Writer struct {
    err error
    buf []byte
    n   int
    wr  io.Writer
}

// Flush writes any buffered data to the underlying io.Writer.
func (b *Writer) Flush() error {
    if b.err != nil {
        return b.err
    }
    if b.n == 0 {
        return nil
    }
    n, err := b.wr.Write(b.buf[0:b.n])
    if n < b.n && err == nil {
        err = io.ErrShortWrite
    }
    if err != nil {
        if n > 0 && n < b.n {
            copy(b.buf[0:b.n-n], b.buf[n:b.n])
        }
        b.n -= n
        b.err = err
        return err
    }
    b.n = 0
    return nil
}

*bufio.Writer.Flush方法执行的是底层io.Writer的Write方法

rotateFile

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// rotateFile closes the syncBuffer's file and starts a new one.
// The startup argument indicates whether this is the initial startup of klog.
// If startup is true, existing files are opened for appending instead of truncated.
func (sb *syncBuffer) rotateFile(now time.Time, startup bool) error {
    if sb.file != nil {
        sb.Flush()
        sb.file.Close()
    }
    var err error
    sb.file, _, err = create(severityName[sb.sev], now, startup)
    if err != nil {
        return err
    }
    if startup {
        fileInfo, err := sb.file.Stat()
        if err != nil {
            return fmt.Errorf("file stat could not get fileinfo: %v", err)
        }
        // init file size
        sb.nbytes = uint64(fileInfo.Size())
    } else {
        sb.nbytes = 0
    }
    sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)

    if sb.logger.skipLogHeaders {
        return nil
    }

    // Write header.
    var buf bytes.Buffer
    fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
    fmt.Fprintf(&buf, "Running on machine: %s\n", host)
    fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
    fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
    n, err := sb.file.Write(buf.Bytes())
    sb.nbytes += uint64(n)
    return err
}

syncBuffer.rotateFile方法会设置其Writer为bufio.NewWriterSize(sb.file, bufferSize),底层writer为syncBuffer的file

小结

klog的init方法异步协程执行logging.flushDaemon(),它内部执行的是l.lockAndFlushAll();Flush方法是执行l.lockAndFlushAll();l.lockAndFlushAll()方法使用lock执行flushAll;flushAll方法从fatalLog开始递减到infoLog级别挨个执行l.file[s]的Flush及Sync方法;对于redirectBuffer,其Flush及Sync方法为空操作;对于syncBuffer,其Sync方法执行的是*os.File.Sync;其Flush方法执行的是*bufio.Writer.Flush,*bufio.Writer.Flush方法执行的是底层io.Writer的Write方法,即syncBuffer的file的Write方法。

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
2 条评论
热度
最新
您好,"使用最好结果进行聚类"这里从哪里可以判断出是最好的结果呢?
您好,"使用最好结果进行聚类"这里从哪里可以判断出是最好的结果呢?
回复回复点赞举报
看完很受启发。我看的关于kmeans对台风路径的聚类的文章基本都是像《K-均值聚类法用于西北太平洋台风路径分类》一样,以路径质心的经纬度和经、纬、对角向的方差作为特征来聚类。请问有没有参考文献是类似你这个方法这样按路径的点计算的欧氏距离,作为两个台风之间的距离,来对路径聚类的呢?期待你的回复~
看完很受启发。我看的关于kmeans对台风路径的聚类的文章基本都是像《K-均值聚类法用于西北太平洋台风路径分类》一样,以路径质心的经纬度和经、纬、对角向的方差作为特征来聚类。请问有没有参考文献是类似你这个方法这样按路径的点计算的欧氏距离,作为两个台风之间的距离,来对路径聚类的呢?期待你的回复~
回复回复点赞举报
推荐阅读
通透!十大聚类算法全总结!!
这些聚类算法各有优缺点,适用于不同类型的数据和不同的应用场景。选择合适的聚类算法通常取决于具体的需求、数据的特性和计算资源。
Python编程爱好者
2023/11/28
6.2K0
通透!十大聚类算法全总结!!
聚类-KMeans算法(图解算法原理)
k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,也就是将数据分成K个簇的算法,其中K是用户指定的。
唔仄lo咚锵
2022/10/04
3.3K0
聚类-KMeans算法(图解算法原理)
估算聚类正确性&使用小批量KMeans来处理更多数据
We talked a little bit about assessing clusters when the ground truth is not known. However, we have not yet talked about assessing KMeans when the cluster is known. In a lot of cases, this isn't knowable; however, if there is outside annotation, we will know the ground truth,or at least the proxy, sometimes.
到不了的都叫做远方
2019/11/22
9350
Using KMeans to cluster data使用K均值来聚类数据
Clustering is a very useful technique. Often, we need to divide and conquer when taking actions. Consider a list of potential customers for a business. A business might need to group customers into cohorts, and then departmentalize responsibilities for these cohorts.Clustering can help facilitate the clustering process.KMeans is probably one of the most well-known clustering algorithms and, in a larger sense, one of the most well-known unsupervised learning techniques.
到不了的都叫做远方
2019/11/20
8660
机器学习 | KMeans聚类分析详解
大量数据中具有"相似"特征的数据点或样本划分为一个类别。聚类分析提供了样本集在非监督模式下的类别划分。聚类的基本思想是"物以类聚、人以群分",将大量数据集中相似的数据样本区分出来,并发现不同类的特征。
数据STUDIO
2021/06/24
4.4K0
机器学习(7)——聚类算法聚类算法
聚类算法 前面介绍的集中算法都是属于有监督机器学习方法,这章和前面不同,介绍无监督学习算法,也就是聚类算法。在无监督学习中,目标属性是不存在的,也就是所说的不存在“y”值,我们是根据内部存在的数据特征,划分不同的类别,使得类别内的数据比较相似。 我们对数据进行聚类的思想不同可以设计不同的聚类算法,本章主要谈论三种聚类思想以及该聚类思想下的三种聚类算法。666 本章主要涉及到的知识点有: “距离” K-Means算法 几种优化K-Means算法 密度聚类 算法思想:“物以类聚,人以群分” 本节首先通过聚类算法
DC童生
2018/04/27
3.8K0
机器学习(7)——聚类算法聚类算法
机器学习第12天:聚类
某位著名计算机科学家有句话:“如果智能是蛋糕,无监督学习将是蛋糕本体,有监督学习是蛋糕上的糖霜,强化学习是蛋糕上的樱桃”
Nowl
2024/01/18
2300
机器学习第12天:聚类
KMeans聚类算法思想与可视化
1.聚类分析 1.0 概念 聚类分析简称聚类(clustering),是一个把数据集划分成子集的过程,每一个子集是一个簇(cluster),使得簇中的样本彼此相似,但与其他簇中的样本不相似。 聚类分析
机器学习AI算法工程
2018/03/12
5K0
KMeans聚类算法思想与可视化
[Python从零到壹] 十三.机器学习之聚类算法四万字总结(K-Means、BIRCH、树状聚类、MeanShift)
在过去,科学家会根据物种的形状习性规律等特征将其划分为不同类型的门类,比如将人种划分为黄种人、白种人和黑种人,这就是简单的人工聚类方法。聚类是将数据集中某些方面相似的数据成员划分在一起,给定简单的规则,对数据集进行分堆,是一种无监督学习。聚类集合中,处于相同聚类中的数据彼此是相似的,处于不同聚类中的元素彼此是不同的。本章主要介绍聚类概念和常用聚类算法,然后详细讲述Scikit-Learn机器学习包中聚类算法的用法,并通过K-Means聚类、Birch层次聚类及PAC降维三个实例加深读者印象。
Eastmount
2021/12/02
2.2K0
[Python从零到壹] 十三.机器学习之聚类算法四万字总结(K-Means、BIRCH、树状聚类、MeanShift)
[Python聚类] 离散点检测 (K-Means聚类方法)
聚类分析用于发现局部强相关的对象组,而异常检测用来发现不与其他对象强相关的对象。  因此,聚类分析可以用于离散度检测。
用户7886150
2020/12/27
2.1K0
复现经典:《统计学习方法》第14章 聚类方法
1.聚类是针对给定的样本,依据它们属性的相似度或距离,将其归并到若干个“类”或“簇”的数据分析问题。一个类是样本的一个子集。直观上,相似的样本聚集在同类,不相似的样本分散在不同类。
黄博的机器学习圈子
2020/06/09
7420
算法复现 | 使用KMEAN算法对印度洋台风路径进行分类
本文根据《K-均值聚类法用于西北太平洋热带气旋路径分类》文献中的聚类方法,对印度洋的台风路径进行聚类分析。 其核心原理就是通过计算每条台风路径的经、纬向质心,以及经、纬、对角向的方差,作为聚类的依据,使用KMEAN算法将上述5个特征进行分类。 最后将分类后的结构进行可视化展示。
郭好奇同学
2022/11/15
1.9K0
算法复现 | 使用KMEAN算法对印度洋台风路径进行分类
AI应用实战课学习总结(7)聚类算法分析实战
今天是我们的第7站,一起了解下聚类算法基本概念 以及 通过聚类算法辅助用户画像的案例。
郑子铭
2025/03/13
1570
AI应用实战课学习总结(7)聚类算法分析实战
公式化调用:Kmeans
kmeans是聚类算法中的一种,通过点与点之间的距离计算,将相近的点聚为一组。聚类结果常用于营销领域的相似用户识别、相似商品识别,欺诈领域的异常点识别等,具体算法介绍可参见文章聚类(二):k-means算法(R&python)。
三猫
2021/09/29
8840
使用Pytorch实现Kmeans聚类
Kmeans是一种简单易用的聚类算法,是少有的会出现在深度学习项目中的传统算法,比如人脸搜索项目、物体检测项目(yolov3中用到了Kmeans进行anchors聚类)等。
带萝卜
2020/10/26
4.4K0
使用Pytorch实现Kmeans聚类
详细介绍了Python聚类分析的各种算法和评价指标
较为详细介绍了聚类分析的各种算法和评价指标,本文将简单介绍如何用python里的库实现它们。
润森
2022/08/18
2.6K0
详细介绍了Python聚类分析的各种算法和评价指标
Sklearn参数详解—聚类算法
聚类是一种非监督学习,是将一份给定数据集划分成k类,这一份数据集可能是某公司的一批用户,也可能是某媒体网站的一系列文章,如果是某公司的一批用户,那么k-means做的就是根据用户的表现对用户的分类;如果媒体的文章,那么k-means做的就是根据文章的类型,把他分到不同的类别。
张俊红
2018/07/30
1.7K0
Sklearn参数详解—聚类算法
机器学习之聚类算法Mean Shift
在K-Means算法中,最终的聚类效果受初始的聚类中心的影响,K-Means++算法的提出,为选择较好的初始聚类中心提供了依据,但是算法中,聚类的类别个数k仍需事先制定,对于类别个数事先未知的数据集,K-Means和K-Means++将很难对其精确求解,对此,有一些改进的算法被提出来处理聚类个数k未知的情形。Mean Shift算法,又被称为均值漂移算法,与K-Means算法一样,都是基于聚类中心的聚类算法,不同的是,Mean Shift算法不需要事先制定类别个数k。
Jetpropelledsnake21
2021/03/12
1.8K0
机器学习之聚类算法Mean Shift
干货|机器学习:Python实现聚类算法之K-Means
1.简介 K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。 K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。 2. 算法大致流程为: 1)随机选取k个点作为种子点(这k个点不一定属于数据集) 2)分别计算每个数据点到k个种子点的距离,离哪个种子点最近,就属于哪类 3)重新计算k个种子点的坐标(简单常用的方法是求坐标值的平均值作为新的坐标值) 4)重复2、3步,直到种子点坐标
灯塔大数据
2018/04/04
2.8K0
干货|机器学习:Python实现聚类算法之K-Means
嘿,敢不敢来聚个类!
A 某和 B 某青梅竹马,A 某通过 B 某认识了 C 某,发现兴趣爱好出奇一致,这三人就搞到了一起,成为了一个形影不离的小团体。这个小团体的形成,是自下而上的迭代过程。
Jack_Cui
2021/04/27
9810
嘿,敢不敢来聚个类!
相关推荐
通透!十大聚类算法全总结!!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档