[{"data":1,"prerenderedAt":422},["ShallowReactive",2],{"nav-stories":3,"footer-stories":61,"project-production-engine":74},[4,16,25,34,43,52],{"id":5,"color":6,"extension":7,"image":8,"label":9,"link":10,"meta":11,"order":12,"stem":13,"text":14,"__hash__":15},"stories\u002Fstories\u002F01-data-center.yml",null,"yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1558494949-ef010cbdcc31?w=1080","DATA_CENTER","https:\u002F\u002Fx.com\u002Fabbeytetteh_",{},1,"stories\u002F01-data-center","Racking new servers. 40gbit backbone online.","0QUZQbaANhdO8WemZxkDdO7vbVopfnynHtH9FxBZb_w",{"id":17,"color":6,"extension":7,"image":18,"label":19,"link":6,"meta":20,"order":21,"stem":22,"text":23,"__hash__":24},"stories\u002Fstories\u002F02-thoughts.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1498050108023-c5249f4df085?w=1080","THOUGHTS",{},2,"stories\u002F02-thoughts","Late night bug hunting. Found the memory leak.","Gd1am954aasY6HRHD7hCtOuessXb6zYZ8iizS501ICg",{"id":26,"color":27,"extension":7,"image":6,"label":28,"link":6,"meta":29,"order":30,"stem":31,"text":32,"__hash__":33},"stories\u002Fstories\u002F03-coding.yml","#3b82f6","CODING",{},3,"stories\u002F03-coding","Just thinking about how much easier life is with Swarm.","vLAyiGUPtlXB2SHa5KM_U2AaK4QkG3Og85UEUE7qzgM",{"id":35,"color":6,"extension":7,"image":36,"label":37,"link":6,"meta":38,"order":39,"stem":40,"text":41,"__hash__":42},"stories\u002Fstories\u002F04-update.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1591799264318-7e6ef8ddb7ea?w=1080","UPDATE",{},4,"stories\u002F04-update","New cluster nodes arrived. Prepping for installation.","kyT60N5C6Re_jMonZbgNy0PbQhzXmUWxDbD0D_v43ts",{"id":44,"color":45,"extension":7,"image":6,"label":46,"link":6,"meta":47,"order":48,"stem":49,"text":50,"__hash__":51},"stories\u002Fstories\u002F05-setup.yml","#86868b","SETUP",{},5,"stories\u002F05-setup","Optimizing the telemetry pipeline for 1M req\u002Fs.","cPOBkzoyXsCmPgRO2d80Hj3vm4MP-6nAejtlQ5iuSzw",{"id":53,"color":6,"extension":7,"image":54,"label":55,"link":6,"meta":56,"order":57,"stem":58,"text":59,"__hash__":60},"stories\u002Fstories\u002F06-travel.yml","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1560969184-10fe8719e047?w=1080","TRAVEL",{},6,"stories\u002F06-travel","Travel log — system architecture workshop in Berlin.","jnOxerdF6usAIHdR35Z-opx0LJAy9kZluXnZhtz62Z0",[62,64,66,68,70,72],{"id":5,"color":6,"extension":7,"image":8,"label":9,"link":10,"meta":63,"order":12,"stem":13,"text":14,"__hash__":15},{},{"id":17,"color":6,"extension":7,"image":18,"label":19,"link":6,"meta":65,"order":21,"stem":22,"text":23,"__hash__":24},{},{"id":26,"color":27,"extension":7,"image":6,"label":28,"link":6,"meta":67,"order":30,"stem":31,"text":32,"__hash__":33},{},{"id":35,"color":6,"extension":7,"image":36,"label":37,"link":6,"meta":69,"order":39,"stem":40,"text":41,"__hash__":42},{},{"id":44,"color":45,"extension":7,"image":6,"label":46,"link":6,"meta":71,"order":48,"stem":49,"text":50,"__hash__":51},{},{"id":53,"color":6,"extension":7,"image":54,"label":55,"link":6,"meta":73,"order":57,"stem":58,"text":59,"__hash__":60},{},{"id":75,"title":76,"body":77,"description":410,"extension":411,"hash":412,"liveUrl":6,"meta":413,"navigation":173,"order":12,"path":414,"rackBay":415,"rackStatus":416,"region":417,"seo":418,"stem":419,"thumbnail":420,"vault":173,"__hash__":421},"projects\u002Fprojects\u002Fproduction-engine.md","Production Engine",{"type":78,"value":79,"toc":405},"minimark",[80,84,89,92,387,391,394,398,401],[81,82,83],"p",{},"Production Engine is the core operational daemon running the KNUST private cloud. It continuously monitors cluster health, collects real-time telemetry from all hypervisors, and triggers autoscaling events when load thresholds are breached.",[85,86,88],"h2",{"id":87},"architecture","Architecture",[81,90,91],{},"The daemon runs as a privileged service on each manager node, communicating with the OpenStack API to provision or decommission compute resources. State is persisted to an embedded SQLite store with a write-ahead log for crash recovery.",[93,94,99],"pre",{"className":95,"code":96,"language":97,"meta":98,"style":98},"language-go shiki shiki-themes vitesse-light","type ClusterMonitor struct {\n    client    *openstack.Client\n    db        *sql.DB\n    threshold ScalingThreshold\n}\n\nfunc (m *ClusterMonitor) EvaluateLoad(ctx context.Context) error {\n    metrics, err := m.client.GetClusterMetrics(ctx)\n    if err != nil {\n        return fmt.Errorf(\"metrics fetch: %w\", err)\n    }\n    if metrics.CPUPercent > m.threshold.ScaleUp {\n        return m.scaleOut(ctx, 1)\n    }\n    return nil\n}\n","go","",[100,101,102,121,140,156,164,169,175,221,256,272,308,314,344,368,373,382],"code",{"__ignoreMap":98},[103,104,106,110,114,117],"span",{"class":105,"line":12},"line",[103,107,109],{"class":108},"sbBg2","type",[103,111,113],{"class":112},"sUxyF"," ClusterMonitor",[103,115,116],{"class":108}," struct",[103,118,120],{"class":119},"sYZai"," {\n",[103,122,123,127,131,134,137],{"class":105,"line":21},[103,124,126],{"class":125},"svycV","    client",[103,128,130],{"class":129},"si04Y","    *",[103,132,133],{"class":112},"openstack",[103,135,136],{"class":119},".",[103,138,139],{"class":112},"Client\n",[103,141,142,145,148,151,153],{"class":105,"line":30},[103,143,144],{"class":125},"    db",[103,146,147],{"class":129},"        *",[103,149,150],{"class":112},"sql",[103,152,136],{"class":119},[103,154,155],{"class":112},"DB\n",[103,157,158,161],{"class":105,"line":39},[103,159,160],{"class":125},"    threshold",[103,162,163],{"class":112}," ScalingThreshold\n",[103,165,166],{"class":105,"line":48},[103,167,168],{"class":119},"}\n",[103,170,171],{"class":105,"line":57},[103,172,174],{"emptyLinePlaceholder":173},true,"\n",[103,176,178,181,184,187,190,193,196,200,203,206,209,211,214,216,219],{"class":105,"line":177},7,[103,179,180],{"class":108},"func",[103,182,183],{"class":119}," (",[103,185,186],{"class":125},"m ",[103,188,189],{"class":129},"*",[103,191,192],{"class":112},"ClusterMonitor",[103,194,195],{"class":119},")",[103,197,199],{"class":198},"sySUi"," EvaluateLoad",[103,201,202],{"class":119},"(",[103,204,205],{"class":125},"ctx",[103,207,208],{"class":112}," context",[103,210,136],{"class":119},[103,212,213],{"class":112},"Context",[103,215,195],{"class":119},[103,217,218],{"class":129}," error",[103,220,120],{"class":119},[103,222,224,227,230,233,236,239,241,244,246,249,251,253],{"class":105,"line":223},8,[103,225,226],{"class":125},"    metrics",[103,228,229],{"class":119},",",[103,231,232],{"class":125}," err",[103,234,235],{"class":119}," :=",[103,237,238],{"class":125}," m",[103,240,136],{"class":119},[103,242,243],{"class":125},"client",[103,245,136],{"class":119},[103,247,248],{"class":198},"GetClusterMetrics",[103,250,202],{"class":119},[103,252,205],{"class":125},[103,254,255],{"class":119},")\n",[103,257,259,262,264,267,270],{"class":105,"line":258},9,[103,260,261],{"class":108},"    if",[103,263,232],{"class":125},[103,265,266],{"class":129}," !=",[103,268,269],{"class":129}," nil",[103,271,120],{"class":119},[103,273,275,278,281,283,286,288,292,296,300,302,304,306],{"class":105,"line":274},10,[103,276,277],{"class":108},"        return",[103,279,280],{"class":125}," fmt",[103,282,136],{"class":119},[103,284,285],{"class":198},"Errorf",[103,287,202],{"class":119},[103,289,291],{"class":290},"sSP4y","\"",[103,293,295],{"class":294},"spphp","metrics fetch: ",[103,297,299],{"class":298},"sEi1f","%w",[103,301,291],{"class":290},[103,303,229],{"class":119},[103,305,232],{"class":125},[103,307,255],{"class":119},[103,309,311],{"class":105,"line":310},11,[103,312,313],{"class":119},"    }\n",[103,315,317,319,322,324,327,330,332,334,337,339,342],{"class":105,"line":316},12,[103,318,261],{"class":108},[103,320,321],{"class":125}," metrics",[103,323,136],{"class":119},[103,325,326],{"class":125},"CPUPercent",[103,328,329],{"class":129}," >",[103,331,238],{"class":125},[103,333,136],{"class":119},[103,335,336],{"class":125},"threshold",[103,338,136],{"class":119},[103,340,341],{"class":125},"ScaleUp",[103,343,120],{"class":119},[103,345,347,349,351,353,356,358,360,362,366],{"class":105,"line":346},13,[103,348,277],{"class":108},[103,350,238],{"class":125},[103,352,136],{"class":119},[103,354,355],{"class":198},"scaleOut",[103,357,202],{"class":119},[103,359,205],{"class":125},[103,361,229],{"class":119},[103,363,365],{"class":364},"s-TwI"," 1",[103,367,255],{"class":119},[103,369,371],{"class":105,"line":370},14,[103,372,313],{"class":119},[103,374,376,379],{"class":105,"line":375},15,[103,377,378],{"class":108},"    return",[103,380,381],{"class":129}," nil\n",[103,383,385],{"class":105,"line":384},16,[103,386,168],{"class":119},[85,388,390],{"id":389},"observability","Observability",[81,392,393],{},"All scaling events are emitted as structured logs consumed by a Loki instance. Grafana dashboards surface cluster utilisation across a 7-day rolling window with per-hypervisor breakdowns.",[85,395,397],{"id":396},"status","Status",[81,399,400],{},"Live in production, handling approximately 200 VMs across 3 availability zones. Average response time for a scale-out event is under 90 seconds from threshold breach to node registration.",[402,403,404],"style",{},"html pre.shiki code .sbBg2, html code.shiki .sbBg2{--shiki-default:#1E754F}html pre.shiki code .sUxyF, html code.shiki .sUxyF{--shiki-default:#2E8F82}html pre.shiki code .sYZai, html code.shiki .sYZai{--shiki-default:#999999}html pre.shiki code .svycV, html code.shiki .svycV{--shiki-default:#B07D48}html pre.shiki code .si04Y, html code.shiki .si04Y{--shiki-default:#AB5959}html pre.shiki code .sySUi, html code.shiki .sySUi{--shiki-default:#59873A}html pre.shiki code .sSP4y, html code.shiki .sSP4y{--shiki-default:#B5695977}html pre.shiki code .spphp, html code.shiki .spphp{--shiki-default:#B56959}html pre.shiki code .sEi1f, html code.shiki .sEi1f{--shiki-default:#A65E2B}html pre.shiki code .s-TwI, html code.shiki .s-TwI{--shiki-default:#2F798A}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":98,"searchDepth":21,"depth":21,"links":406},[407,408,409],{"id":87,"depth":21,"text":88},{"id":389,"depth":21,"text":390},{"id":396,"depth":21,"text":397},"A custom-built live monitoring and autoscaling daemon for the KNUST Cloud, ensuring high availability across all cluster nodes.","md","A1B2C3",{},"\u002Fprojects\u002Fproduction-engine","BAY 01","live","AF-SOUTH-1",{"title":76,"description":410},"projects\u002Fproduction-engine","\u002Fimages\u002Fthumbnails\u002Fproduction-engine.png","KC6VHsNbYyyWtTidhS6I8zgUmAdY2fxxqSOzaRqsqsg",1779361989070]