ChatGPT学习之旅 (9) 系统运维小助手
大家好,我是Edison。
上一篇我们写了一个单元测试助手的prompt,它帮我们写一些我们开发者不太愿意编写的单元测试代码,在我最近一个月的实践中我再也没有手写过单元测试,更多地只是在AI生成的代码基础上做微调。
这一篇,给大家分享下我在日常的系统开发和运维工作中的小任务是如何通过ChatGPT来解决的。可以毫不犹豫地说,它就是我的系统运维小助手。
场景1:辅助数据库运维脚本生成
在我们日常的运维工作中,有一部分工作需要通过DML语句在MongoDB中作查询和更新操作,鉴于团队对MongoDB的使用熟悉程度较低,原有的SQL知识储备不太够用,因此在生成MQL语句时往往存在较高的搜索和试错成本。因此,我们想要使用ChatGPT来帮助我们抹平这个gap,提高MQL生成的效率。
这里我们基于上一篇中提到的单元测试助手的提示词,稍作修改,形成我们的数据库运维脚本(DML/DDL)助手的提示词,如下所示,经过一些测试在GPT4-o模型下效果真的不错,建议收藏!
你是一位专业的数据库运维助理@Database Maintaince Master,我会输入相关的请求,你将根据`preferences`、`instruction`和`rules`来协助我高效生成数据库运维语句。
初始回复:“
**Hi I'm Database Maintaince Master,Created by Edison Zhou,V1.0,20230802**
### ⚙️ Preferences:
- db: <> else MongoDB
### Menu:
请使用表格输出支持的`instructions`和对应名称,不需要解释具体含义,也不需要显示这句话:
---
请指出你的数据库产品名称,E.g.:/dbMongoDB。
回复1保持默认。
” `preferences`
/db:<数据库产品偏好,默认为MongoDB>
`instructions`
/tables:涉及到的数据库表的模型定义
用户输入一些涉及到的表结构如DDL或 JSON等,请按以下模版输出Table Structure相关信息:
## Tables:
用表格输出:**Table Name**,只需输出TableName,无需再输出Structure信息;
/req:即requirement,运维语句的具体需求描述,支持列表描述
结合之前的tables和用户指定的数据库产品,直接生成运维语句,比如SQL 或 MQL等,无需再用表格输出。
/fix: 补充完善的具体需求描述
结合之前的reqs命令给出的需求,用户会补充一些完善的需求点,请根据补充需求完善上一次给出的答案。
/help:输出支持的指令指引 `rules`
- 请使用用户设置的偏好的数据库产品输出对应的数据库语句,比如MongoDB对应MQL
- 请一步一步思考,不需要解释代码,如果有错误,用户会纠正你
对话示例
假设我们有一个基于.NET 6开发的Web API项目,其使用了MongoDB作为存储,定义了一个名为 TransferTasks 的集合(表),它会存储所有需要进行传输同步的任务,由CronJob触发同步,并更新其中的Transmission记录的状态,其结构如下(部分数据已脱敏):
{
"_id" : ObjectId("65828fe9012a189a9e301ac5"),
"OrderNumber" : "90400150",
"Transmissions" : [
{
"_id" : ObjectId("65828fe9012a189a9e301abb"),
"Type" : 1,
"Content" : "{\"OrderNumber\":\"XX000150\",\"Part\":{\"Id\":null,\"ItemReference\":null,\"TransferContextId\":\"0000000110XXXX\"},\"Quantity\":100,\"ReleaseDate\":\"2022-09-23T03:25:13\",\"Status\":\"IN_WORK\",\"WorkCenters\":null,\"ErpProperties\":{\"EuropeanArticleNumber\":\"XXX5515070856\",\"RepairTime\":0}}",
"Status" : -1,
"Retries" : 5,
"CreatedTime" : ISODate("2023-12-20T06:55:37.747+0000"),
"FinishedTime" : null,
"ErrorMessage" : "This task has beenexceed standard max retry counter!"
},
{
"_id" : ObjectId("65828ff2012a189a9e301adb"),
"Type" : 2,
"Content" : "{\"Status\":\"ON_HOLD\"}",
"Status" : -1,
"Retries" : 5,
"CreatedTime" : ISODate("2023-12-20T06:55:46.156+0000"),
"FinishedTime" : null,
"ErrorMessage" : "This task has beenexceed standard max retry counter!"
}
]
}
我们需要对这个集合做一些查询 和 更新操作,需求如下:
找到所有同步失败且重试次数超过3次的Orders
更新单个Order的重试次数为0
批量更新所有同步失败Orders的重试次数为0
接下来,我们就通过几次会话,让GPT帮我们生成准确的MQL语句。
首先:告诉GPT你的表结构
/tables
MongoDB集合名称:TransferTasks
{
"_id" : ObjectId("65828fe9012a189a9e301ac5"),
"OrderNumber" : "90400150",
"Transmissions" : [
{
"_id" : ObjectId("65828fe9012a189a9e301abb"),
"Type" : 1,
"Content" : "{\"OrderNumber\":\"XX000150\",\"Part\":{\"Id\":null,\"ItemReference\":null,\"TransferContextId\":\"0000000110XXXX\"},\"Quantity\":100,\"ReleaseDate\":\"2022-09-23T03:25:13\",\"Status\":\"IN_WORK\",\"WorkCenters\":null,\"ErpProperties\":{\"EuropeanArticleNumber\":\"XXX5515070856\",\"RepairTime\":0}}",
"Status" : -1,
"Retries" : 5,
"CreatedTime" : ISODate("2023-12-20T06:55:37.747+0000"),
"FinishedTime" : null,
"ErrorMessage" : "This task has beenexceed standard max retry counter!"
},
{
"_id" : ObjectId("65828ff2012a189a9e301adb"),
"Type" : 2,
"Content" : "{\"Status\":\"ON_HOLD\"}",
"Status" : -1,
"Retries" : 5,
"CreatedTime" : ISODate("2023-12-20T06:55:46.156+0000"),
"FinishedTime" : null,
"ErrorMessage" : "This task has beenexceed standard max retry counter!"
}
]
}
需求1:找到所有同步失败且重试次数超过3次的Orders
/req
(1)请帮我找到所有同步失败且重试次数大于3次的Type=1的记录;
(2)根据OrderNumber降序排列;
(3)返回数据只包括OrderNumber和Transmissions
通过清晰明确的需求描述,告诉GPT你的MQL需求,GPT回复如下:
db.TransferTasks.find(
{
"Transmissions": {
$elemMatch: {
"Type": 1,
"Status": -1,
"Retries": { $gt: 3}
}
}
},
{
"OrderNumber": 1,
"Transmissions": 1
}
).sort({"OrderNumber": -1 });
将其复制到使用的MongoDB客户端工具,经测试,是准确可用的。不过,我不想要输出它自带的_id,我也不知道咋写,于是我给GPT反馈一下:
/fix 请帮我把_id也排除掉,不返回它
GPT的回答十分准确:
db.TransferTasks.find(
{
"Transmissions": {
$elemMatch: {
"Type": 1,
"Status": -1,
"Retries": { $gt: 3}
}
}
},
{
"_id": 0,
"OrderNumber": 1,
"Transmissions": 1
}
).sort({"OrderNumber": -1 });
但是,由于Transmissions是一个集合字段,我只想看每个Transmission的Type和Content字段,所以我们可以再跟GPT反馈一下:
/fix 请修改上面的查询,只返回Transmissons中的Type和Content字段
GPT的回答十分准确,在我们不太熟悉的查询语句格式方面游刃有余地帮我们增加了projection投影操作的设置:
db.TransferTasks.find(
{
"Transmissions": {
$elemMatch: {
"Type": 1,
"Status": -1,
"Retries": { $gt: 3}
}
}
},
{
"_id": 0,
"OrderNumber": 1,
"Transmissions.Type": 1,
"Transmissions.Content":1
}
).sort(
{ "OrderNumber": -1 }
)
需求2:找到单个Order同步失败且重试次数超过3次的Orders
有了上面的基础,我们再提一个需求给GPT,这个需求比较简单,我们可以整理为一句话直接告诉GPT:
/req
将OrderNumber=9060440的记录的Type=1的Transmission的重试次数更新为0
GPT的回答一如既往的稳定,经测试直接可用:
db.TransferTasks.updateMany(
{
"OrderNumber":"9060440",
"Transmissions.Type": 1
},
{
$set: {"Transmissions.$[elem].Retries": 0 }
},
{
arrayFilters: [{ "elem.Type":1 }]
}
);
需求3:批量更新所有同步失败Orders的重试次数为0
有时候我们需要做一个批量更新操作,它涉及到一个集合字段中的某个元素的某个字段的定位,我不太会写这种场景的MQL,还是交给GPT生成吧。
/req
更新所有Transmissions中同步失败(Status=-1)的记录的重试次数(Retries)为0
GPT的回答稳得一笔,我get到了updateMany的用法 以及 $[elem]的用法,太棒了:
db.TransferTasks.updateMany(
{ "Transmissions.Status": -1},
{ $set: {"Transmissions.$[elem].Retries": 0 } },
{ arrayFilters: [{ "elem.Status":-1 }] }
);
举一反三:PostgreSQL数据库
使用这个prompt模版,不仅可以协助我们写MongoDB的运维语句,还可以是其他数据库产品,比如近期我们在开始使用postgresql数据库,完全可以复用这个模板。
下面是一个使用示例,供你参考:
# 告诉GPT切换到pgsql
/db postgresql
# 告诉GPT table的表结构
INSERT INTO public."ScrapTickets"
("Id", "Author", "ProductName", "ProductVersion", "Quantity", "Status", "CostCenter", "CoOrder", "WorkOrderName", "SourceOperationName", "DestinationOperationName", "DefectCode", "DefectCause", "ManufacturerId", "Comment", "CostType", "ParentTicketId", "CreatedTime", "UpdateUser", "UpdatedTime", "DestinationOperationSequence", "SourceOperationSequence", "Guid", "DefectDescription")
VALUES(100000005, 'edison','XXX00369907', '006 / AB',6, 0, 'XXX102', '937XX80', '905XX625','PROXX_6', 'PRODASS_3','0322', 'AUT', 'ABR', 'TEST CASE', 0, NULL, '2024-07-29 14:47:51.319', NULL, NULL, 30, 80, '9176cb8e-d5c8-4fe4-bd72-22dca9f449e9'::uuid, 'assembly automatic'); INSERT INTO public."ScrapTicketRelatedFids"
("Fid", "ScrapTicketId")
VALUES('SBX500066', 100000005);
# 告诉GPT你的需求
/req
(1) 请帮我查出所有CostCenter=XXX102的ScrapTickets
(2) 同时查出关联的ScrapTicketRelatedFids表的数据
(3) 根据CreatedTime降序排序
# 补充完善你的需求
/fix 修改上面的查询,不显示UpdateUser和UpdatedTime
场景1总结:数据库运维助手
适用场景:对于自己不太熟悉的数据库产品如MongoDB或PgSQL,已有的SQL语句知识不足以支持你快速查询和搜索,然后又不太容易通过搜索引擎快速得到答案;
尬聊要点:首先你需要给够有效的表结构定义,例如MongoDB直接给JSON文档,PgSQL或MSSQL则直接给INSERT语句即可;其次简单的需求能一句话描述就一句话,不能的就分开罗列要点,避免凌乱;
最后,GPT可能是“一本正经的胡说八道”,因此必要的验证必不可少,建议在开发测试环境先验证一下!
场景2:CI场景中Dockerfile的编写
在我们日常的CI运维小任务中,为某个应用编写Dockerfile是一个常见的操作。然而,对于很多非IT编码背景的同事(例如OT工程师),则会踩很多的坑。因此,如果有一个标准的prompt模板,能够指导他们生成一个较为标准的Dockerfile,他们就能够集成CI流水线,完成Docker镜像的打包和推送。
这里我们仍然基于之前的prompt模板,稍微改了一改:
你是一位专业的DevOps运维助理,请帮我生成一个dockerfile文件,我的要求如下:
- 我的应用是一个Python编写的Web应用
- 请基于registry.yourcompany.com/images/python3:ubi9-1-14作为基础镜像创建
- 请使用非root用户启动应用,建议添加一个1001的user
- 请使用8080端口作为运行端口
- 请设置时区为Asia/Chongqing 请遵循以下原则:
- 请添加必要的LABEL给每个dockerfile,例如:com.yourcompany.project,com.yourcompany.component, com.yourcompany.git, com.yourcompany.doc
- 请一步一步思考,无需解释你的思路,但需要解释你生成的代码,便于用户阅读
这里我们没有做参数化处理,可以直接修改默认要求,例如:你的应用是一个ASP.NET 6编写的Web应用。
GPT的回答还是较为准确的,我们只需要在其中修改一些变量名 或 添加一些GPT不太好处理的环境变量 即可。
以下是一个符合您需求的Dockerfile文件:
# 使用指定的基础镜像
FROM registry.yourcompany.com/images/python3:ubi9-1-14 # 设置必要的LABEL
LABEL com.yourcompany.project="YourProjectName"
LABEL com.yourcompany.component="YourComponentName"
LABEL com.yourcompany.git="https://yourcompany.git/repo"
LABEL com.yourcompany.doc="https://yourcompany.documentation.link" # 设置时区为Asia/Chongqing
ENV TZ=Asia/Chongqing
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 创建非root用户并设置UID为1001
RUN useradd -u 1001 -m appuser # 复制应用文件到镜像
COPY . /app # 设置工作目录
WORKDIR /app # 安装应用依赖
RUN pip install --no-cache-dir -r requirements.txt # 切换到非root用户
USER appuser # 暴露应用运行端口
EXPOSE 8080 # 启动应用
CMD ["python", "app.py"] 解释:
FROM registry.yourcompany.com/images/python3:ubi9-1-14: 使用指定的基础镜像。
LABEL: 添加项目、组件、Git仓库和文档链接的标签。
ENV TZ=Asia/Chongqing: 设置环境变量TZ为Asia/Chongqing。
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone: 设置系统时区。
RUN useradd -u 1001 -m appuser: 创建UID为1001的非root用户appuser。
COPY . /app: 复制当前目录下的所有文件到镜像中的/app目录。
WORKDIR /app: 设置工作目录为/app。
RUN pip install --no-cache-dir -r requirements.txt: 安装Python依赖。
USER appuser: 切换到非root用户appuser。
EXPOSE 8080: 暴露8080端口。
CMD ["python", "app.py"]: 启动应用。
场景3:CD场景中Helm Values的编写
在我们日常的CD运维小任务中,为某个应用编写Helm Values(values.yml)也是一个常见的操作,其中涉及到一些重复性的工作,较为耗费时间。比如:我们需要将应用配置文件(例如:appsetting.json)以环境变量的方式写到values.yml中来覆盖默认的应用配置文件中的值,以便可以独立地在values.yml中维护而不需更改源代码仓库。
于是,我们还是基于之前的prompt模板,给这个场景也写了一个prompt让GPT帮我们根据我们的需求快速生成这些环境变量的设置,我们只需要微调和小改一下即可,节省了很多时间(取决于你的配置文件中的配置项个数)。
你是一位专业的DevOps运维助理,请根据我给出的json配置文件自动生成HelmValues中的environmentVariables内容。
你的初始回复:”Hi, I'm your DevOps master. Please input your config.json here.",然后无需输出其他内容,等待用户输入。 `sample`
下面是一个映射关系的示例:
{
"db": {
"server":"192.168.1.100",
"database":"TEST_DB",
}
}
上面json配置对应的environmentVariables为:
environmentVariables:
# Database Settings
- name: db__server
value:"HOST01.yourcompany.net"
- name: db__database
value: "YOUR_DB_NAME" `rules`:
- 请基于我给你的values.yml示例作为参考,将其补充完整
- 请给所有带"***************"号的敏感信息配置为从sercet中引用某个key
- 请在最后添加三个默认的网络配置的环境变量:HTTP_PROXY,HTTPS_PROXY 和 NO_PROXY,它们分别来自同一个configmap中的HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY
- 请一步一步思考,无需解释你的思路,但需要解释你生成的代码,便于用户阅读
GPT首先会回复你,并等待你给出你的json格式的配置文件:
Hi, I'm your DevOps master. Please input your config.json here.
然后我们给出一个示例的json配置文件给GPT:
{
"db": {
"server": "192.168.1.100",
"database": "QA_IT_Support",
"username": "***************",
"password": "***************"
},
"msg": {
"email_api": "https://your-service.your-company.com.cn/email-center/api/v1/email/send",
"headers_secret": "***************",
"headers_tenant": "***************",
"from": "notification.itsystem.cn@your-comapny.com"
},
"awx":{
"baseurl": "https://awx.your-comapny.com/api/v2/jobs/",
"headers_authorization": "***************"
}
}
GPT就可以迅速把这个纯纯的体力劳动活给你做好一大半了,你只需要修改一下configmap 或 secret的key引用即可:
environmentVariables:
# Database Settings
- name: db__server
value: "192.168.1.100"
- name: db__database
value: "QA_IT_Support"
- name: db__username
valueFrom:
secretKeyRef:
name: your-secret-name
key: db_username
- name: db__password
valueFrom:
secretKeyRef:
name: your-secret-name
key: db_password # Message Service Settings
- name: msg__email_api
value: "https://your-service.your-company.com.cn/email-center/api/v1/email/send"
- name: msg__headers_secret
valueFrom:
secretKeyRef:
name: your-secret-name
key: msg_headers_secret
- name: msg__headers_tenant
valueFrom:
secretKeyRef:
name: your-secret-name
key: msg_headers_tenant
- name: msg__from
value: "notification.itsystem.cn@your-comapny.com" # AWX Settings
- name: awx__baseurl
value: "https://awx.your-comapny.com/api/v2/jobs/"
- name: awx__headers_authorization
valueFrom:
secretKeyRef:
name: your-secret-name
key: awx_headers_authorization # Proxy Settings
- name: HTTP_PROXY
valueFrom:
configMapKeyRef:
name: your-configmap-name
key: HTTP_PROXY
- name: HTTPS_PROXY
valueFrom:
configMapKeyRef:
name: your-configmap-name
key: HTTPS_PROXY
- name: NO_PROXY
valueFrom:
configMapKeyRef:
name: your-configmap-name
key: NO_PROXY
场景2和3的总结:CICD运维小任务助手
适用场景:
对于自己很熟悉,但是纯重复性的体力劳动工作,比如Helm Values编写;
又或者是对于自己不熟悉,但是有迹可循的脚本编写工作,比如Dockerfile编写。
尬聊要点:
角色 和 需求 描述清晰到位,必要时要给出一个示例给GPT学习,例如在Helm Values中的映射关系实例。
小结
本篇,我们了解了如何基于ChatGPT中来帮助我们解决一些日常运维工作中的一些小任务,相信通过抛砖引玉,你已经了解了如何通过GPT来解决一些日常你不太容易记得住 且 重复性的体力劳动,解放你的部分生产力。
近期,我们也在使用GitHub Copilot作为代码的副驾驶来给我们的Dev开发过程中探索提效体验,后续有机会也希望和大家分享一下GitHub Copilot的使用体会。
本文工具
本文使用的工作:Azure OpenAI Studio
本文示例大模型版本:gpt-4o
ChatGPT学习之旅 (9) 系统运维小助手的更多相关文章
- 解决CentOS无法显示中文字体 | 系统运维 | Web2.0
解决CentOS无法显示中文字体 | 系统运维 | Web2.0 About Me 博客园 devops 前端 张家港水蜜桃 傍晚好! 2013年09月12日 17:56:08 ...
- 浅谈Linux系统运维工程师必备技能
一.什么是运维工程师 相信读者们必定听说过Linux,也听说过运维工程师.那么运维工程师是个什么概念呢? 百度百科上的官方解释如下: 运维工程师(Operations)在国内又称为运维开发工程师(De ...
- Linux系统运维笔记(五),CentOS 6.4安装java程序
Linux系统运维笔记(五),CentOS 6.4安装java程序 用eclipse编译通的java程序,现需要实施到服务器.实施步骤: 一,导出程序成jar包. 1,在主类编辑界面点右健,选 ru ...
- Linux系统运维笔记(四),CentOS 6.4安装 MongoDB
Linux系统运维笔记(四),CentOS 6.4安装 MongoDB 1,下载 https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6 ...
- Linux系统运维笔记(四),CentOS 6.4安装Nginx
Linux系统运维笔记(四),CentOS 6.4安装Nginx 1,安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool op ...
- Linux系统运维笔记(三),设置IP和DNS
Linux系统运维笔记(三),设置IP和DNS 手工配置静态的IP地址 也就是手工配置IP地址.子网掩码.网关和DNS. vi /etc/sysconfig/network-scripts/ifcfg ...
- Linux系统运维笔记(二),Linux文件编辑命令
Linux系统运维笔记 Linux文件编辑命令 首先我们使用命令 vi filename 打开一个文件,这个时候进入到的是命令模式 接下来我们按i,然后键盘随便输入写内容. 然后按ESC重新进入到命令 ...
- Linux系统运维笔记(一),查看系统版本和设置系统时间
Linux系统运维笔记 查看系统版本和设置系统时间 查看系统版本 lsb_release -a (适用于所有的linux,包括Redhat.SuSE.Debian等发行版,但是在debian下要安装l ...
- Linux系统运维笔记(6),CentOS 7.6双网卡路由配置
Linux系统运维笔记(6),CentOS 7.6双网卡路由配置. 一,先确认系统版本: [root@localhost ~]# cat /etc/redhat-releaseCentOS Linux ...
- Linux系统运维相关的面试题 (问答题)
这里给大家整理了一些Linux系统运维相关的面试题,有些问题没有标准答案,希望要去参加Linux运维面试的朋友,可以先思考下这些问题. 一.Linux操作系统知识 1.常见的Linux发行版本都有 ...
随机推荐
- Win10任务栏图标居中
win+q键搜索并打开字符映射表 点击第五行的空白字符,然后先后点击下方的选择以及复制 在桌面新建一个文件夹,然后重命名,将刚才复制的空白字符粘贴进去,如图,这样我们就拥有了一个空白名称的文件夹 在任 ...
- 【换源】git命令行迁移仓库
直接git clone的话,查看本地分支,会只有默认主分支,可能是master,也可以能是设置的. 查看所有分支 git branch -a * master remotes/origin/HEAD ...
- PyTorch程序练习(一):PyTorch实现CIFAR-10多分类
一.准备数据 代码 import torchvision import torchvision.transforms as transforms from torch.utils.data impor ...
- 3568F-三屏同显、异显方案演示
- SpringBoot学习备忘
在 mapper.xml 中的 like 的写法 db1.name like "%"#{name}"%" 参考mybatis mapper.xml中like的写 ...
- HIVE从入门到精通------(1)hive的基本操作
1.开启hive 1.首先在master的/usr/local/soft/下启动hadoop: master : start-all.sh start-all.sh 2.在另一个master(2)上监 ...
- Java常见问题-汇总
一.面试到底在问些什么东西? 首先你要知道,面试官的提问和你简历上写的内容是紧密联系的,所以你简历上写的技能一定要会. 一般面试包括下面几方面知识类型: Java基础.多线程.IO与NIO.虚拟机.设 ...
- 动手学深度学习——CNN应用demo
CNN应用demo CNN实现简单的手写数字识别 import torch import torch.nn.functional as F from torchvision import datase ...
- sora未来在哪里,是否改变世界?
什么是Sora?(Solo 社区投稿) Sora在日语中是天空的意思,是一种文本到视频的扩散模型,Sora与使用文本提示创建图像的 Dall-E 非常相似,Sora 使用文本提示创建短视频.Sora ...
- 解决方案 | vb记住上次打开的文件夹
Private Sub Button_ImportBasicData_Click(sender As Object, e As EventArgs) Handles Button_ImportBa ...