func (fd *Feeder) ServeLogFeeds() {
	fd.WgServer.Add(1)
	defer fd.WgServer.Done()
	if err := fd.LogServer.Serve(fd.Listener); err != nil {
		kg.Print("Terminated the gRPC service")
	}
}
=============== //
== Log Feeds == //
=============== //
ServeLogFeeds Function
package feeder
import (
	"bufio"
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
	kl "github.com/kubearmor/KubeArmor/KubeArmor/common"
	kg "github.com/kubearmor/KubeArmor/KubeArmor/log"
	tp "github.com/kubearmor/KubeArmor/KubeArmor/types"
	"github.com/google/uuid"
	pb "github.com/kubearmor/KubeArmor/protobuf"
	"google.golang.org/grpc"
)
var Running bool
var MsgQueue chan pb.Message
var AlertQueue chan pb.Alert
var LogQueue chan pb.Log
func init() {
	Running = true
	MsgQueue = make(chan pb.Message, 1024)
	AlertQueue = make(chan pb.Alert, 4096)
	LogQueue = make(chan pb.Log, 32768)
}
type MsgStruct struct {
	Client pb.LogService_WatchMessagesServer
	Filter string
}
type AlertStruct struct {
	Client pb.LogService_WatchAlertsServer
	Filter string
}
type LogStruct struct {
	Client pb.LogService_WatchLogsServer
	Filter string
}
type LogService struct {
	MsgStructs map[string]MsgStruct
	MsgLock    *sync.RWMutex
	AlertStructs map[string]AlertStruct
	AlertLock    *sync.RWMutex
	LogStructs map[string]LogStruct
	LogLock    *sync.RWMutex
}
func (ls *LogService) HealthCheck(ctx context.Context, nonce *pb.NonceMessage) (*pb.ReplyMessage, error) {
	replyMessage := pb.ReplyMessage{Retval: nonce.Nonce}
	return &replyMessage, nil
}
func (ls *LogService) addMsgStruct(uid string, srv pb.LogService_WatchMessagesServer, filter string) {
	ls.MsgLock.Lock()
	defer ls.MsgLock.Unlock()
	msgStruct := MsgStruct{}
	msgStruct.Client = srv
	msgStruct.Filter = filter
	ls.MsgStructs[uid] = msgStruct
}
func (ls *LogService) removeMsgStruct(uid string) {
	ls.MsgLock.Lock()
	defer ls.MsgLock.Unlock()
	delete(ls.MsgStructs, uid)
}
func (ls *LogService) getMsgStructs() []MsgStruct {
	msgStructs := []MsgStruct{}
	ls.MsgLock.RLock()
	defer ls.MsgLock.RUnlock()
	for _, mgs := range ls.MsgStructs {
		msgStructs = append(msgStructs, mgs)
	}
	return msgStructs
}
func (ls *LogService) WatchMessages(req *pb.RequestMessage, svr pb.LogService_WatchMessagesServer) error {
	uid := uuid.Must(uuid.NewRandom()).String()
	ls.addMsgStruct(uid, svr, req.Filter)
	defer ls.removeMsgStruct(uid)
	for Running {
		msg := <-MsgQueue
		msgStructs := ls.getMsgStructs()
		for _, mgs := range msgStructs {
			if err := mgs.Client.Send(&msg); err != nil {
				kg.Err("Failed to send a message")
			}
		}
	}
	return nil
}
func (ls *LogService) addAlertStruct(uid string, srv pb.LogService_WatchAlertsServer, filter string) {
	ls.AlertLock.Lock()
	defer ls.AlertLock.Unlock()
	alertStruct := AlertStruct{}
	alertStruct.Client = srv
	alertStruct.Filter = filter
	ls.AlertStructs[uid] = alertStruct
}
func (ls *LogService) removeAlertStruct(uid string) {
	ls.AlertLock.Lock()
	defer ls.AlertLock.Unlock()
	delete(ls.AlertStructs, uid)
}
func (ls *LogService) getAlertStructs() []AlertStruct {
	alertStructs := []AlertStruct{}
	ls.AlertLock.RLock()
	defer ls.AlertLock.RUnlock()
	for _, als := range ls.AlertStructs {
		alertStructs = append(alertStructs, als)
	}
	return alertStructs
}
func (ls *LogService) WatchAlerts(req *pb.RequestMessage, svr pb.LogService_WatchAlertsServer) error {
	uid := uuid.Must(uuid.NewRandom()).String()
	ls.addAlertStruct(uid, svr, req.Filter)
	defer ls.removeAlertStruct(uid)
	for Running {
		alert := <-AlertQueue
		alertStructs := ls.getAlertStructs()
		for _, als := range alertStructs {
			if err := als.Client.Send(&alert); err != nil {
				kg.Err("Failed to send an alert")
			}
		}
	}
	return nil
}
func (ls *LogService) addLogStruct(uid string, srv pb.LogService_WatchLogsServer, filter string) {
	ls.LogLock.Lock()
	defer ls.LogLock.Unlock()
	logStruct := LogStruct{}
	logStruct.Client = srv
	logStruct.Filter = filter
	ls.LogStructs[uid] = logStruct
}
func (ls *LogService) removeLogStruct(uid string) {
	ls.LogLock.Lock()
	defer ls.LogLock.Unlock()
	delete(ls.LogStructs, uid)
}
func (ls *LogService) getLogStructs() []LogStruct {
	logStructs := []LogStruct{}
	ls.LogLock.RLock()
	defer ls.LogLock.RUnlock()
	for _, lgs := range ls.LogStructs {
		logStructs = append(logStructs, lgs)
	}
	return logStructs
}
func (ls *LogService) WatchLogs(req *pb.RequestMessage, svr pb.LogService_WatchLogsServer) error {
	uid := uuid.Must(uuid.NewRandom()).String()
	ls.addLogStruct(uid, svr, req.Filter)
	defer ls.removeLogStruct(uid)
	for Running {
		log := <-LogQueue
		logStructs := ls.getLogStructs()
		for _, lgs := range logStructs {
			if err := lgs.Client.Send(&log); err != nil {
				kg.Err("Failed to send a log")
			}
		}
	}
	return nil
}
type Feeder struct {
	ClusterName string
	Node *tp.Node
	Port string
	Output  string
	LogFile *os.File
	Listener net.Listener
	LogServer *grpc.Server
	WgServer sync.WaitGroup
	SecurityPolicies     map[string]tp.MatchPolicies
	SecurityPoliciesLock *sync.RWMutex
	IsGKE bool
}
func NewFeeder(clusterName string, node *tp.Node, port, output string) *Feeder {
	fd := &Feeder{}
	fd.ClusterName = clusterName
	fd.Node = node
	fd.Port = fmt.Sprintf(":%s", port)
	fd.Output = output
	if fd.Output != "stdout" && fd.Output != "none" {
		dirLog := filepath.Dir(fd.Output)
		if _, err := os.Stat(filepath.Clean(fd.Output)); os.IsNotExist(err) {
			if err := os.MkdirAll(filepath.Clean(dirLog), 0750); err != nil {
				kg.Errf("Failed to create a target directory (%s, %s)", dirLog, err.Error())
				return nil
			}
			targetFile, err := os.Create(filepath.Clean(fd.Output))
			if err != nil {
				kg.Errf("Failed to create a target file (%s, %s)", fd.Output, err.Error())
				return nil
			}
			if err := targetFile.Close(); err != nil {
				kg.Err(err.Error())
			}
		}
		logFile, err := os.OpenFile(filepath.Clean(fd.Output), os.O_WRONLY|os.O_APPEND, 0600)
		if err != nil {
			kg.Err(err.Error())
			return nil
		}
		fd.LogFile = logFile
	}
	listener, err := net.Listen("tcp", fd.Port)
	if err != nil {
		kg.Errf("Failed to listen a port (%s, %s)", fd.Port, err.Error())
		return nil
	}
	fd.Listener = listener
	fd.LogServer = grpc.NewServer()
	logService := &LogService{
		MsgStructs:   make(map[string]MsgStruct),
		MsgLock:      &sync.RWMutex{},
		AlertStructs: make(map[string]AlertStruct),
		AlertLock:    &sync.RWMutex{},
		LogStructs:   make(map[string]LogStruct),
		LogLock:      &sync.RWMutex{},
	}
	pb.RegisterLogServiceServer(fd.LogServer, logService)
	fd.WgServer = sync.WaitGroup{}
	fd.SecurityPolicies = map[string]tp.MatchPolicies{}
	fd.SecurityPoliciesLock = new(sync.RWMutex)
	if kl.IsInK8sCluster() {
		if b, err := ioutil.ReadFile(filepath.Clean("/media/root/etc/os-release")); err == nil {
			s := string(b)
			if strings.Contains(s, "Container-Optimized OS") {
				fd.IsGKE = true
			}
		}
	}
	return fd
}
func (fd *Feeder) DestroyFeeder() error {
	Running = false
	time.Sleep(time.Second * 1)
	if fd.Listener != nil {
		if err := fd.Listener.Close(); err != nil {
			kg.Err(err.Error())
		}
		fd.Listener = nil
	}
	if fd.LogFile != nil {
		if err := fd.LogFile.Close(); err != nil {
			kg.Err(err.Error())
		}
		fd.LogFile = nil
	}
	fd.WgServer.Wait()
	return nil
}
func (fd *Feeder) StrToFile(str string) {
	if fd.LogFile != nil {
		str = str + "\n"
		w := bufio.NewWriter(fd.LogFile)
		if _, err := w.WriteString(str); err != nil {
			kg.Err(err.Error())
		}
		if err := w.Flush(); err != nil {
			kg.Err(err.Error())
		}
	}
}
func (fd *Feeder) Print(message string) {
	fd.PushMessage("INFO", message)
	kg.Print(message)
}
func (fd *Feeder) Printf(message string, args ...interface{}) {
	str := fmt.Sprintf(message, args...)
	fd.PushMessage("INFO", str)
	kg.Print(str)
}
func (fd *Feeder) Debug(message string) {
	fd.PushMessage("DEBUG", message)
	kg.Debug(message)
}
func (fd *Feeder) Debugf(message string, args ...interface{}) {
	str := fmt.Sprintf(message, args...)
	fd.PushMessage("DEBUG", str)
	kg.Debug(str)
}
func (fd *Feeder) Err(message string) {
	fd.PushMessage("ERROR", message)
	kg.Err(message)
}
func (fd *Feeder) Errf(message string, args ...interface{}) {
	str := fmt.Sprintf(message, args...)
	fd.PushMessage("ERROR", str)
	kg.Err(str)
}
func (fd *Feeder) Warn(message string) {
	fd.PushMessage("WARN", message)
	kg.Warn(message)
}
func (fd *Feeder) Warnf(message string, args ...interface{}) {
	str := fmt.Sprintf(message, args...)
	fd.PushMessage("WARN", str)
	kg.Warnf(str)
}