ELK---Python实现Mysql数据导入到ES,及Geoip数据类型写入

使用环境:Python3.6

准备Py包:  elasticsearch、geoip2、pymysql

下面上代码

1.导入必要的模块

# encoding:utf-8

from elasticsearch import Elasticsearch
from elasticsearch import helpers
import geoip2.database
import pymysql

2.封装获取Mysql数据的函数,按指定参数传入即可,并返回结果集

    def get_data(host, port, user, password, database, sql):
        """
        :param host: 服务器地址
        :param port:端口号
        :param user:用户名
        :param password:密码
        :param database:数据库
        :param sql:执行语句
        :return:结果集
        """
        db = pymysql.connect(host=host, port=port, user=user, password=password, database=database)
        cursor = db.cursor()
        cursor.execute(sql)
        dt = cursor.fetchall()
        db.close()
        return dt

3.封装获取IP地址对应地理信息的函数

def select_ip(ip):
    """
    :param ip:Ip地址
    :return:返回拼凑的Body数据
    """
    reader = geoip2.database.Reader(
        'F:\logstash-7.3.1\config\GeoLite2-City.mmdb')  # 这里引用的是我本地logstash的GeoIP的数据包,按照本机路径替换掉即可
    data = reader.city(ip)
    body_son = {}
    body_son["country_code2"] = data.country.iso_code  # 国家
    body_son["longitude"] = data.location.longitude  # 经度
    body_son["timezone"] = data.location.time_zone  # 时区
    body_son["ip"] = data.traits.ip_address  # Ip地址
    body_son["country_code3"] = data.registered_country.iso_code  # 注册国家
    body_son[
        "region_code"] = data.subdivisions.most_specific.iso_code  # 区域代码 subdivisions的属性 要通过 most_specific点出来,暂没发现原因
    body_son["latitude"] = data.location.latitude  # 维度
    body_son["country_name"] = data.country.names['en']  # 国家名称
    body_son["location"] = {"lon": data.location.longitude, "lat": data.location.latitude}  # 经纬坐标
    body_son["continent_code"] = data.continent.code  # 大洲
    return body_son

4.封装批量插入ES数据的函数

    def insert_batch_index(server, port, actions):
        """
        :param server: 服务器地址
        :param port: 端口号
        :param actions:数据列表
        """
        es = Elasticsearch([server], prot=port)
        res = helpers.bulk(es, actions)

5.最终执行主体函数(以下我的示例代码,具体参数值,根据中文注释修改为自身的参数即可)

# 写入登录数据到ES
def main():
    # 获取Mysql登录数据
    login_data = GetDataMethod.get_data(host='192.168.40.9', port=3306, user='root', password='123456',
                                        database='wechat',
                                        sql='select LoginID,LanIP,OpenTime,TotalAmount from  sys_re_agentlogin where LoginID<=1500')
    es_body = {
        "mappings": {
            # es 7 默认不再支持指定索引类型,默认索引类型是_doc,索引不能指定索引类型参数
            "properties": {
                "LoginID": {"type": "long"},
                "LanIP": {"type": "text"},
                "OpenTime": {"type": "date"},
                "TotalAmount": {"type": "text"},
                "geoip.ip": {"type": "ip"},
                "geoip.location": {"type": "geo_point"}
            }
        }
    }
    # 创建索引
    EsMethod.create_index('py_wechat_login', '192.168.99.100', 9200, es_body)
    # 写入数据
    actions = []
    for dt_son in login_data:
        action = {
            "_index": 'py_wechat_login', #索引名称
            "_type": '_doc',  #索引类型,默认_doc,最好不要改动
            "_id": dt_son[0], #记录ID
            "_source": {
                "LoginID": dt_son[0],
                "LanIP": dt_son[1],
                "OpenTime": dt_son[2],
                "TotalAmount": dt_son[3],
                "geoip": select_ip(dt_son[1])
            }
        }
        actions.append(action)
    insert_batch_index('192.168.99.100', 9200, actions)

结尾:过程中其实还是碰到不少问题的,这是最终完整处理后可以运行的结果,有疑问的童鞋可以评论交流!

------------原创,纯手打,觉得对您有帮助的话,帮忙点个赞哦!

你可能感兴趣的:(数据可视化,Python)